Commit 27799937 authored by Nemo Ma's avatar Nemo Ma

ADD: Branched Dialogue

parent 7d488cb3
......@@ -423,6 +423,108 @@ if($hp > 0){
else{
$mode='command';
}
} elseif(strpos($command,'dialogue_choice') === 0) {
// 处理对话选择
$choice_parts = explode(' ', $command);
if(count($choice_parts) >= 3) {
$dialogue_id = $choice_parts[1];
$choice_index = $choice_parts[2];
// 检查对话 ID 和选择索引是否有效
if(isset($dialogue_branch[$dialogue_id]) && isset($dialogue_branch[$dialogue_id][$choice_index])) {
// 记录玩家的选择
$clbpara['dialogue_choice'] = array(
'dialogue_id' => $dialogue_id,
'choice_index' => $choice_index,
'choice_text' => $dialogue_branch[$dialogue_id][$choice_index]
);
// 输出选择的结果
$log .= "你选择了:<span class=\"yellow\">{$dialogue_branch[$dialogue_id][$choice_index]}</span><br>";
// 添加非常明显的错误信息
$log .= "<div style='background-color: red; color: white; padding: 10px; margin: 10px; border: 2px solid black;'>对话选择调试信息: 对话 ID = {$dialogue_id}, 选择索引 = {$choice_index}</div>";
// 如果有对应的选择结果日志,显示它
$choice_log_key = $dialogue_id.'_choice_'.$choice_index;
// 调试信息,显示对话日志的键值
$log .= "<!-- DEBUG: 对话 ID: {$dialogue_id}, 选择索引: {$choice_index}, 选择日志键: {$choice_log_key} -->";
// 显示所有可用的对话日志键
$log .= "<!-- DEBUG: 可用的对话日志键: ";
foreach($dialogue_log as $key => $value) {
$log .= "{$key}, ";
}
$log .= " -->";
if(isset($dialogue_log[$choice_log_key]) && !empty($dialogue_log[$choice_log_key])) {
$log .= "<!-- DEBUG: 使用选择特定日志 -->";
$log .= $dialogue_log[$choice_log_key];
} elseif(isset($dialogue_log[$dialogue_id]) && !empty($dialogue_log[$dialogue_id])) {
// 如果没有特定选择的日志,显示通用日志
$log .= "<!-- DEBUG: 使用通用日志 -->";
$log .= $dialogue_log[$dialogue_id];
} else {
$log .= "<!-- DEBUG: 没有找到对应的对话日志 -->";
}
// 清除对话状态
unset($clbpara['dialogue']);
unset($clbpara['noskip_dialogue']);
// 确保对话框不会重新打开
$dialogue_id = null;
$opendialog = null;
// 保存玩家数据,确保选择被记录
$serialized_clbpara = serialize($clbpara);
$encoded_clbpara = base64_encode($serialized_clbpara);
$log .= "<!-- DEBUG: 序列化后的 clbpara 长度: " . strlen($serialized_clbpara) . " -->";
$log .= "<!-- DEBUG: 编码后的 clbpara 长度: " . strlen($encoded_clbpara) . " -->";
$update_query = "UPDATE {$tablepre}players SET clbpara='" . $encoded_clbpara . "' WHERE pid='$pid'";
$update_result = $db->query($update_query);
if($update_result) {
$log .= "<!-- DEBUG: 数据库更新成功 -->";
// 验证数据库中的值是否正确
$verify_query = "SELECT clbpara FROM {$tablepre}players WHERE pid='$pid'";
$verify_result = $db->query($verify_query);
if($verify_result && $db->num_rows($verify_result) > 0) {
$verify_data = $db->fetch_array($verify_result);
$db_clbpara = $verify_data['clbpara'];
$log .= "<!-- DEBUG: 数据库中的 clbpara 长度: " . strlen($db_clbpara) . " -->";
// 尝试解码和反序列化
try {
$decoded_clbpara = base64_decode($db_clbpara);
$unserialized_clbpara = unserialize($decoded_clbpara);
if(is_array($unserialized_clbpara) && isset($unserialized_clbpara['dialogue_choice'])) {
$log .= "<!-- DEBUG: 数据库中的 dialogue_choice 存在 -->";
} else {
$log .= "<!-- DEBUG: 数据库中的 dialogue_choice 不存在 -->";
}
} catch(Exception $e) {
$log .= "<!-- DEBUG: 反序列化失败: " . $e->getMessage() . " -->";
}
} else {
$log .= "<!-- DEBUG: 无法验证数据库中的值 -->";
}
} else {
$log .= "<!-- DEBUG: 数据库更新失败: " . $db->error() . " -->";
}
// 设置命令模式为命令模式,确保页面能够正确显示选择结果
$mode = 'command';
} else {
$log .= "<span class=\"red\">无效的对话选择!</span><br>";
}
} else {
$log .= "<span class=\"red\">对话选择格式错误!</span><br>";
}
} elseif(strpos($command,'end_dialogue') === 0) {
//$log.="【DEBUG】关闭了对话框。";
if(!empty($dialogue_log[$clbpara['dialogue']])) $log.= $dialogue_log[$clbpara['dialogue']];
......@@ -785,7 +887,10 @@ if($hp > 0){
$gamedata['innerHTML']['ingamebgm'] = $bgm_player;
}
//检查执行动作后是否有对话框产生
if(!empty($clbpara['dialogue']))
//如果刚刚处理了对话选择,则不显示对话框
$just_made_choice = strpos($command, 'dialogue_choice') === 0;
if(!$just_made_choice && !empty($clbpara['dialogue']))
{
$opendialog = 'dialogue';
$dialogue_id = $clbpara['dialogue'];
......@@ -853,6 +958,9 @@ $gamedata['innerHTML']['anum'] = $alivenum;
ob_clean();
$main ? include template($main) : include template('profile');
$gamedata['innerHTML']['main'] = ob_get_contents();
// 添加调试信息,显示最终的 log 变量状态
$log .= "<!-- DEBUG: 最终的 log 变量长度: " . strlen($log) . " -->";
$gamedata['innerHTML']['log'] = $log;
if(isset($error)){$gamedata['innerHTML']['error'] = $error;}
$gamedata['value']['teamID'] = $teamID;
......
# 对话选择系统实现文档
## 概述
本文档记录了对话选择系统的设计与实现过程。对话选择系统允许玩家在对话中选择不同的选项,从而影响游戏的进程。
## 系统设计
### 数据结构
1. **对话内容**:在`gamedata/cache/dialogue_1.php`中定义,使用`$dialogues`数组存储对话内容。
2. **对话选项**:在`gamedata/cache/dialogue_1.php`中定义,使用`$dialogue_branch`数组存储对话选项。
3. **选择结果**:在`gamedata/cache/dialogue_1.php`中定义,使用`$dialogue_log`数组存储选择结果。
4. **玩家选择记录**:在玩家数据的`$clbpara['dialogue_choice']`中记录玩家的选择。
### 流程设计
1. 玩家触发对话(通常是使用物品或进入特定区域)。
2. 系统显示对话内容,玩家可以翻页查看。
3. 当对话到达最后一页时,系统显示选项。
4. 玩家选择一个选项,系统记录选择并显示相应的结果。
5. 对话结束,系统清除对话状态。
## 实现细节
### 1. 对话数据定义
在`gamedata/cache/dialogue_1.php`中定义对话内容、选项和结果:
```php
// 对话内容
$dialogues = Array(
'choiceTestingDialog' => Array(
0 => '这是带选择的测试对话第一页',
1 => '这是带选择的测试对话第二页',
2 => '请选择下面的选项:',
),
);
// 对话选项
$dialogue_branch = Array(
'choiceTestingDialog' => Array(
'选项A','选项B','选项C',
),
);
// 选择结果
$dialogue_log = Array(
'choiceTestingDialog' => Array(
0 => '你选择了选项A',
1 => '你选择了选项B',
2 => '你选择了选项C',
),
);
```
### 2. 对话界面实现
在`templates/default/dialogue.htm`中实现对话界面:
```html
<dialog id="dialogue" style="width: 460px; max-width: 90%;max-height: 80%;">
<script src="include/dialogue.js?v=<!--{eval time();}-->"></script>
<p><center>
<!-- 当前阅读页面 -->
<div id="dmarkpage" style="display: none;">0</div>
<!-- 对话框尾页 -->
<!--{eval $endpage = count($dialogues[$dialogue_id])-1;}-->
<!--{eval $maxdkey = $endpage + 1;}-->
<div id="dendpage" style="display: none;">$endpage</div>
<!-- 对白分段显示 -->
<!--{loop $dialogues[$dialogue_id] $dkey $dinfo}-->
<div id="d{$dkey}" <!--{if $dkey == 0}--> class="ach_box" style="overflow-y: auto; border:0; text-align: center; min-height: min-content; width: max-content; max-width: 560px;" <!--{else}--> style="display: none;" <!--{/if}-->>
<table>
<tr>
<!-- 带头像对白 -->
<!--{if isset($dialogue_icon[$dialogue_id][$dkey])}-->
<td>
<img style="width:140px;height:80px;" src="$dialogue_icon[$dialogue_id][$dkey]">
</td>
<td class="ach-cont" style="border: 1px; width:280px;height:80px;text-align: left; padding: 3% 6%;">
$dinfo
</td>
<!-- 无头像对白 -->
<!--{else}-->
<td class="ach-cont" style="width:320px;height:80px;text-align: center; padding: 3% 6%;">
$dinfo
</td>
<!--{/if}-->
</tr>
</table>
<br>
<!--{if $dkey > 0}-->
<input type="button" class="cmdbutton" id="i" style="margin-right: 5%;" value="[I]上一页" onclick="changePages('d',-1);">
<!--{/if}-->
<!--{if (($dkey <= ($endpage-1)) || (isset($dialogue_branch[$dialogue_id])))}-->
<input type="button" class="cmdbutton" id="p" value="[P]下一页" onclick="changePages('d',1);">
<!--{elseif isset($dialogue_end[$dialogue_id])}-->
$dialogue_end[$dialogue_id]
<!--{/if}-->
</div>
<!--{/loop}-->
<!-- 选择肢显示 -->
<!--{if isset($dialogue_branch[$dialogue_id])}-->
<div id="d{$maxdkey}" style="display: none;" class="ach_box">
<table border="0" style="text-align: center;"><tr><td style="width:320px;height:80px; text-align: center; padding: 3% 6%;">
<div style="margin-bottom: 10px;">请选择:</div>
<!--{loop $dialogue_branch[$dialogue_id] $bkey $binfo}-->
<input type="button" class="cmdbutton" style="margin: 5px; display: block; width: 200px;" value="$binfo" onclick="handleDialogueChoice('{$dialogue_id}', '{$bkey}'); return false;">
<!--{/loop}-->
</td></tr></table>
</div>
<!--{/if}-->
</center></p>
<!--{if (isset($dialogue_branch[$dialogue_id]) || isset($dialogue_end[$dialogue_id]))}-->
<img class="dialog-background" src="img/profile.gif" onclick="">
<!--{else}-->
<img class="dialog-background" src="img/profile.gif" onclick="closeDialog($('dialogue'));$('command').value='end_dialogue';postCmd('gamecmd','command.php');this.disabled=true;">
<!--{/if}-->
</dialog>
```
### 3. JavaScript实现
在`include/dialogue.js`中实现对话翻页和选择处理:
```javascript
// 对话系统的JavaScript扩展
// 扩展changePages函数,处理对话选择页面
function dialogueChangePages(mode, cPages) {
var nowpage = Number(document.getElementById(mode + 'markpage').innerHTML);
var endpage = Number(document.getElementById(mode + 'endpage').innerHTML);
var maxdkey = endpage + 1; // 选择页面的ID
if(nowpage < 0 || nowpage > endpage) {
nowpage = 0;
}
var nextpage = nowpage + cPages;
document.getElementById(mode + 'markpage').innerHTML = nextpage;
// 隐藏当前页面
var currentPage = document.getElementById(mode + nowpage);
if(currentPage) {
currentPage.style.display = "none";
}
// 如果下一页是选择页面
if(nextpage > endpage) {
// 显示选择页面
var choicePage = document.getElementById(mode + maxdkey);
if(choicePage) {
choicePage.style.display = "block";
}
} else {
// 显示普通对话页面
var dialoguePage = document.getElementById(mode + nextpage);
if(dialoguePage) {
dialoguePage.style.display = "block";
}
}
}
// 处理对话选择
function handleDialogueChoice(dialogueId, choiceIndex) {
try {
// 禁用所有选择按钮,防止重复点击
var choiceButtons = document.querySelectorAll('#dialogue input.cmdbutton');
if (choiceButtons && choiceButtons.length > 0) {
for(var i = 0; i < choiceButtons.length; i++) {
choiceButtons[i].disabled = true;
}
}
// 设置命令值
var commandInput = document.getElementById('command');
if(commandInput) {
commandInput.value = 'dialogue_choice ' + dialogueId + ' ' + choiceIndex;
} else {
return false;
}
// 关闭对话框
var dialogueElement = document.getElementById('dialogue');
if(dialogueElement) {
try {
// 在关闭对话框前添加一个"处理中"的提示
var processingDiv = document.createElement('div');
processingDiv.innerHTML = '<span style="color: yellow; font-weight: bold;">正在处理选择...</span>';
processingDiv.style.textAlign = 'center';
processingDiv.style.padding = '10px';
dialogueElement.appendChild(processingDiv);
// 延迟关闭对话框,给用户一个反馈
setTimeout(function() {
try {
dialogueElement.close();
} catch (closeError) { }
// 在关闭对话框后再提交命令
setTimeout(function() {
try {
postCmd('gamecmd', 'command.php');
} catch (postError) {
// 如果提交命令出错,尝试直接提交表单
try {
document.getElementById('gamecmd').submit();
} catch (submitError) { }
}
}, 100);
}, 500);
} catch (processError) {
// 如果处理对话框出错,直接提交命令
postCmd('gamecmd', 'command.php');
}
} else {
// 如果没有找到对话框,也要提交命令
setTimeout(function() {
postCmd('gamecmd', 'command.php');
}, 100);
}
} catch (error) {
// 如果出现任何错误,尝试直接提交命令
try {
var commandInput = document.getElementById('command');
if(commandInput) {
commandInput.value = 'dialogue_choice ' + dialogueId + ' ' + choiceIndex;
}
postCmd('gamecmd', 'command.php');
} catch (finalError) { }
}
return false;
}
```
### 4. 命令处理实现
在`command.php`中实现对话选择命令处理:
```php
// 处理对话选择
if(strpos($command, 'dialogue_choice') === 0) {
$parts = explode(' ', $command);
if(count($parts) >= 3) {
$dialogue_id = $parts[1];
$choice_index = $parts[2];
// 检查对话ID和选择索引是否有效
if(isset($dialogue_branch[$dialogue_id]) && isset($dialogue_branch[$dialogue_id][$choice_index])) {
// 记录玩家的选择
if(!isset($clbpara['dialogue_choice'])) {
$clbpara['dialogue_choice'] = array();
}
$clbpara['dialogue_choice'][$dialogue_id] = $choice_index;
// 显示选择结果
if(isset($dialogue_log[$dialogue_id][$choice_index])) {
$log .= "<span class=\"yellow\">{$dialogue_log[$dialogue_id][$choice_index]}</span><br>";
} else {
$log .= "<span class=\"yellow\">你选择了:{$dialogue_branch[$dialogue_id][$choice_index]}</span><br>";
}
// 清除对话状态
unset($clbpara['dialogue']);
unset($clbpara['noskip_dialogue']);
// 设置命令模式为命令模式,确保页面能够正确显示选择结果
$mode = 'command';
} else {
$log .= "<span class=\"red\">无效的对话选择!</span><br>";
}
} else {
$log .= "<span class=\"red\">对话选择格式错误!</span><br>";
}
}
```
### 5. 对话触发实现
在`include/game/item.test.php`中实现对话触发:
```php
} elseif ($itm == '对话选择测试器') {
// 带选择的对话测试
$clbpara['dialogue'] = 'choiceTestingDialog';
$clbpara['noskip_dialogue'] = 1; // 设置为不可跳过的对话
}
```
### 6. 对话框显示修复
在`game.php`中修复对话框显示:
```php
// 检查是否有对话需要显示,但如果刚刚处理了对话选择,则不显示
// 通过检查 $_POST['command'] 是否包含 'dialogue_choice' 来判断
$just_made_choice = isset($_POST['command']) && strpos($_POST['command'], 'dialogue_choice') === 0;
if(!$just_made_choice && (!empty($clbpara['dialogue']) || !empty($clbpara['noskip_dialogue'])))
{
$opendialog = $clbpara['noskip_dialogue'] ? 'dialogue' : 'dialogue';
if(!empty($clbpara['dialogue'])) $dialogue_id = $clbpara['dialogue'];
}
if(isset($opendialog))
{
$log.="<script>
var dialogElement = document.getElementById('{$opendialog}');
if(dialogElement && dialogElement.showModal) {
dialogElement.showModal();
}
</script>";
}
```
## 修复记录
### 1. 模板语法错误修复
在`templates/default/dialogue.htm`文件中,第2行使用了原始的PHP代码`<?php echo time(); ?>`,而不是模板系统的语法`{eval time()}`。这导致模板编译后的文件中出现了语法错误。
修复方法:将原始的PHP代码替换为模板系统的语法。
```html
<script src="include/dialogue.js?v=<!--{eval time();}-->"></script>
```
### 2. 选择页面显示修复
在`templates/default/dialogue.htm`中,添加了`$maxdkey`变量的定义,用于确定选择页面的ID。
```html
<!--{eval $endpage = count($dialogues[$dialogue_id])-1;}-->
<!--{eval $maxdkey = $endpage + 1;}-->
```
### 3. 对话框关闭后重新打开问题修复
在`game.php`中,添加了检查,确保在处理完对话选择后不会重新打开对话框。
```php
$just_made_choice = isset($_POST['command']) && strpos($_POST['command'], 'dialogue_choice') === 0;
if(!$just_made_choice && (!empty($clbpara['dialogue']) || !empty($clbpara['noskip_dialogue'])))
{
// ...
}
```
### 4. 选择按钮样式改进
在`templates/default/dialogue.htm`中,改进了选择按钮的样式,使其更加明显。
```html
<input type="button" class="cmdbutton" style="margin: 5px; display: block; width: 200px;" value="$binfo" onclick="handleDialogueChoice('{$dialogue_id}', '{$bkey}'); return false;">
```
## 使用方法
### 1. 定义对话内容
在`gamedata/cache/dialogue_1.php`中定义对话内容、选项和结果:
```php
// 对话内容
$dialogues = Array(
'myDialogue' => Array(
0 => '这是第一页对话',
1 => '这是第二页对话',
2 => '请选择下面的选项:',
),
);
// 对话选项
$dialogue_branch = Array(
'myDialogue' => Array(
'选项A','选项B','选项C',
),
);
// 选择结果
$dialogue_log = Array(
'myDialogue' => Array(
0 => '你选择了选项A',
1 => '你选择了选项B',
2 => '你选择了选项C',
),
);
```
### 2. 触发对话
在游戏代码中,使用以下代码触发对话:
```php
$clbpara['dialogue'] = 'myDialogue';
$clbpara['noskip_dialogue'] = 1; // 设置为不可跳过的对话
```
### 3. 处理选择结果
在游戏代码中,使用以下代码处理选择结果:
```php
if(isset($clbpara['dialogue_choice']['myDialogue'])) {
$choice = $clbpara['dialogue_choice']['myDialogue'];
if($choice == 0) {
// 处理选项A的结果
} elseif($choice == 1) {
// 处理选项B的结果
} elseif($choice == 2) {
// 处理选项C的结果
}
}
```
## 注意事项
1. 对话ID必须唯一,且在`$dialogues`、`$dialogue_branch`和`$dialogue_log`中保持一致。
2. 选择索引必须从0开始,且在`$dialogue_branch`和`$dialogue_log`中保持一致。
3. 如果不需要显示选择结果,可以不定义`$dialogue_log`。
4. 如果需要对话框不可跳过,必须设置`$clbpara['noskip_dialogue'] = 1`。
5. 在处理选择结果时,必须检查`$clbpara['dialogue_choice']`是否存在,以避免错误。
## 未来改进
1. 添加对话分支功能,根据玩家的选择显示不同的对话内容。
2. 添加对话条件功能,根据玩家的状态显示不同的选项。
3. 添加对话图标功能,为对话添加头像或图标。
4. 添加对话音效功能,为对话添加音效。
5. 添加对话动画功能,为对话添加动画效果。
......@@ -5,7 +5,7 @@ require './include/common.inc.php';
require GAME_ROOT.'./include/game.func.php';
if(!$cuser||!$cpass) { gexit($_ERROR['no_login'],__file__,__line__); }
if(!$cuser||!$cpass) { gexit($_ERROR['no_login'],__file__,__line__); }
if(isset($mode) && $mode == 'quit') {
gsetcookie('user','');
......@@ -128,7 +128,7 @@ if($action == 'corpse' || $action == 'pacorpse' && $gamestate<40){
init_battle_rev($pdata,$edata,1);
$main = 'battle_rev';
}
}
}
}
elseif($action == 'chase' || $action == 'pchase' || $action == 'dfight'){
$enemyid = $bid;
......@@ -152,7 +152,7 @@ elseif($action == 'neut'){
init_battle_rev($pdata,$edata,1);
$main = 'battle_rev';
}
}
}
}
if($hp > 0 && $coldtimeon && $showcoldtimer && $rmcdtime){$log .= "行动冷却时间:<span id=\"timer\" class=\"yellow\">0.0</span>秒<script type=\"text/javascript\">demiSecTimerStarter($rmcdtime);</script><br>";}
//如果身上存在时效性技能,检查技能是否超时
......@@ -180,7 +180,11 @@ if ($club==0)
getclub($name,$c1,$c2,$c3);
$clubavl[0]=0; $clubavl[1]=$c1; $clubavl[2]=$c2; $clubavl[3]=$c3;
}
if(!empty($clbpara['dialogue']) || !empty($clbpara['noskip_dialogue']))
// 检查是否有对话需要显示,但如果刚刚处理了对话选择,则不显示
// 通过检查 $_POST['command'] 是否包含 'dialogue_choice' 来判断
$just_made_choice = isset($_POST['command']) && strpos($_POST['command'], 'dialogue_choice') === 0;
if(!$just_made_choice && (!empty($clbpara['dialogue']) || !empty($clbpara['noskip_dialogue'])))
{
$opendialog = $clbpara['noskip_dialogue'];
if(!empty($clbpara['dialogue'])) $dialogue_id = $clbpara['dialogue'];
......@@ -188,10 +192,13 @@ if(!empty($clbpara['dialogue']) || !empty($clbpara['noskip_dialogue']))
if(isset($opendialog))
{
$log.="<script>
$('{$opendialog}').showModal();
var dialogElement = document.getElementById('{$opendialog}');
if(dialogElement && dialogElement.showModal) {
dialogElement.showModal();
}
</script>";
}
//if (!strstr($_SERVER['HTTP_REFERER'], 'php') && $_SERVER['HTTP_REFERER'] != '') {
if (isset($_GET['is_new'])) {
include './api.php';
......
......@@ -58,6 +58,14 @@ $dialogues = Array
1 => '这是测试对话第二页',
2 => '现在给出选择支',
),
// 带选择的测试对话
'choiceTestingDialog' => Array
(
0 => '这是带选择的测试对话第一页',
1 => '这是带选择的测试对话第二页',
2 => '请选择下面的选项:',
),
);
# 单组对白中哪一页对话会显示头像:
......@@ -76,6 +84,10 @@ $dialogue_log = Array
'thiphase' => "<span class='lime'>※ 权限重载完成,控制模块已解锁。</span><br>……这又是什么时候的事?<br><br>",
'club21entry' => "<span class='yellow'>虽然打开了蛋,但你被其中的<span class='glitchb'>数据风暴</span>狂暴吸入,受到了大量的伤害!</span><br>你屁滚尿流地重新站了起来。<br><br>",
'testingDialog' => "<span class='yellow'>测试已结束!</span><br><br>",
'choiceTestingDialog' => "<span class='yellow'>选择测试已结束!</span><br><br>",
'choiceTestingDialog_choice_0' => "<span class='yellow'>你选择了选项A!</span><br>这是选项A的结果。<br><br>",
'choiceTestingDialog_choice_1' => "<span class='yellow'>你选择了选项B!</span><br>这是选项B的结果。<br><br>",
'choiceTestingDialog_choice_2' => "<span class='yellow'>你选择了选项C!</span><br>这是选项C的结果。<br><br>",
);
# 单组对白结束时提供选择肢:
......@@ -90,6 +102,9 @@ $dialogue_branch = Array
//5 => '选项C',
'选项A','选项B','选项C',
),
'choiceTestingDialog' => Array(
'选项A','选项B','选项C',
),
);
# 单组对白结束提供特殊结束按钮(非必须、仅在结束对白会触发特殊事件时调用):
......
// 对话系统的JavaScript扩展
// 扩展changePages函数,处理对话选择页面
function dialogueChangePages(mode, cPages) {
console.log('dialogueChangePages called with mode=' + mode + ', cPages=' + cPages);
var nowpage = Number(document.getElementById(mode + 'markpage').innerHTML);
var endpage = Number(document.getElementById(mode + 'endpage').innerHTML);
var maxdkey = endpage + 1; // 选择页面的ID
console.log('Current page: ' + nowpage + ', End page: ' + endpage + ', Choice page ID: ' + maxdkey);
if(nowpage < 0 || nowpage > endpage) {
nowpage = 0;
console.log('Reset nowpage to 0');
}
var nextpage = nowpage + cPages;
console.log('Next page: ' + nextpage);
document.getElementById(mode + 'markpage').innerHTML = nextpage;
// 隐藏当前页面
var currentPage = document.getElementById(mode + nowpage);
if(currentPage) {
currentPage.style.display = "none";
console.log('Hiding current page: ' + mode + nowpage);
} else {
console.error('Current page not found: ' + mode + nowpage);
}
// 如果下一页是选择页面
if(nextpage > endpage) {
console.log('Next page is choice page');
// 显示选择页面
var choicePage = document.getElementById(mode + maxdkey);
console.log('Looking for choice page with ID: ' + mode + maxdkey);
// 列出所有可用的元素ID
console.log('Available elements:');
var allElements = document.getElementsByTagName('*');
for(var i=0; i<allElements.length; i++) {
if(allElements[i].id && allElements[i].id.startsWith(mode)) {
console.log('- ' + allElements[i].id);
}
}
if(choicePage) {
choicePage.style.display = "block";
console.log("Showing choice page: " + mode + maxdkey);
} else {
console.error("Choice page not found: " + mode + maxdkey);
}
} else {
console.log('Next page is dialogue page');
// 显示普通对话页面
var dialoguePage = document.getElementById(mode + nextpage);
if(dialoguePage) {
dialoguePage.style.display = "block";
console.log("Showing dialogue page: " + mode + nextpage);
} else {
console.error("Dialogue page not found: " + mode + nextpage);
}
}
}
// 覆盖原有的changePages函数
function changePages(mode, cPages) {
// 如果是对话系统,使用dialogueChangePages
if(mode === 'd') {
dialogueChangePages(mode, cPages);
} else {
// 否则使用原有的逻辑
var nowpage = Number(document.getElementById(mode + 'markpage').innerHTML);
var endpage = Number(document.getElementById(mode + 'endpage').innerHTML);
if(nowpage < 0 || nowpage > endpage) {
nowpage = 0;
}
var nextpage = nowpage + cPages;
document.getElementById(mode + 'markpage').innerHTML = nowpage + cPages;
var currentPage = document.getElementById(mode + nowpage);
if(currentPage) {
currentPage.style.display = "none";
}
var nextPageElement = document.getElementById(mode + nextpage);
if(nextPageElement) {
nextPageElement.style.display = "inline-block";
}
var prevButton = document.getElementById('shooting_previous');
if(prevButton) {
prevButton.style.display = nextpage > 0 ? 'inline-block' : 'none';
}
var nextButton = document.getElementById('shooting_next');
if(nextButton) {
nextButton.style.display = (nextpage >= endpage) ? 'none' : 'inline-block';
}
var endingButton = document.getElementById('shooting_ending');
if(endingButton) {
endingButton.style.display = (nextpage == endpage) ? 'inline-block' : 'none';
}
}
}
// 处理对话选择
function handleDialogueChoice(dialogueId, choiceIndex) {
// 添加非常明显的控制台日志
console.log('%c对话选择调试信息', 'background: red; color: white; font-size: 20px;');
console.log('%c对话 ID = ' + dialogueId + ', 选择索引 = ' + choiceIndex, 'background: red; color: white; font-size: 20px;');
console.log('handleDialogueChoice called with dialogueId=' + dialogueId + ', choiceIndex=' + choiceIndex);
try {
// 禁用所有选择按钮,防止重复点击
var choiceButtons = document.querySelectorAll('#dialogue input.cmdbutton');
if (choiceButtons && choiceButtons.length > 0) {
for(var i = 0; i < choiceButtons.length; i++) {
choiceButtons[i].disabled = true;
}
console.log('All choice buttons disabled');
} else {
console.warn('No choice buttons found to disable');
}
// 设置命令值
var commandInput = document.getElementById('command');
if(commandInput) {
commandInput.value = 'dialogue_choice ' + dialogueId + ' ' + choiceIndex;
console.log('Command set to: ' + commandInput.value);
} else {
console.error('Command input not found!');
return false;
}
// 关闭对话框
var dialogueElement = document.getElementById('dialogue');
if(dialogueElement) {
try {
// 在关闭对话框前添加一个“处理中”的提示
var processingDiv = document.createElement('div');
processingDiv.innerHTML = '<span style="color: yellow; font-weight: bold;">正在处理选择...</span>';
processingDiv.style.textAlign = 'center';
processingDiv.style.padding = '10px';
dialogueElement.appendChild(processingDiv);
// 延迟关闭对话框,给用户一个反馈
setTimeout(function() {
try {
dialogueElement.close();
console.log('Dialogue closed');
} catch (closeError) {
console.error('Error closing dialogue:', closeError);
}
// 在关闭对话框后再提交命令
setTimeout(function() {
console.log('Submitting command...');
try {
postCmd('gamecmd', 'command.php');
console.log('Command submitted');
} catch (postError) {
console.error('Error posting command:', postError);
// 如果提交命令出错,尝试直接提交表单
try {
document.getElementById('gamecmd').submit();
console.log('Form submitted directly');
} catch (submitError) {
console.error('Error submitting form:', submitError);
}
}
}, 100);
}, 500);
} catch (processError) {
console.error('Error processing dialogue:', processError);
// 如果处理对话框出错,直接提交命令
postCmd('gamecmd', 'command.php');
}
} else {
console.error('Dialogue element not found!');
// 如果没有找到对话框,也要提交命令
setTimeout(function() {
console.log('Submitting command anyway...');
postCmd('gamecmd', 'command.php');
}, 100);
}
} catch (error) {
console.error('Error in handleDialogueChoice:', error);
// 如果出现任何错误,尝试直接提交命令
try {
var commandInput = document.getElementById('command');
if(commandInput) {
commandInput.value = 'dialogue_choice ' + dialogueId + ' ' + choiceIndex;
}
postCmd('gamecmd', 'command.php');
} catch (finalError) {
console.error('Final error attempt failed:', finalError);
}
}
console.log('Dialogue choice submitted: dialogue_choice ' + dialogueId + ' ' + choiceIndex);
return false;
}
function hotkey(evt)
{
function hotkey(evt)
{
if(document.activeElement.tagName != 'INPUT'){
evt = (evt) ? evt : ((window.event) ? window.event : '');
var ky = evt.keyCode ? evt.keyCode : evt.which;
......@@ -8,7 +8,7 @@ function hotkey(evt)
$('submit').click();
}
}
}
}
}
//update time
......@@ -29,7 +29,7 @@ function updateTime(timing,mode)
setTimeout("updateTime(t,tm)",1000);
}
else{
window.location.reload();
window.location.reload();
}
}
......@@ -128,7 +128,7 @@ function sl(id) {
// } else{
// $(id).innerHTML = '';
// }
//
//
// }
// if(gamedata['timer'] && typeof(timerid)=='undefined'){
// demiSecTimerStarter(gamedata['timer']);
......@@ -165,7 +165,7 @@ function sl(id) {
// $(id).innerHTML = regdata[id];
// } else{
// $(id).innerHTML = '';
// }
// }
// }
//}
......@@ -202,9 +202,9 @@ function sl(id) {
//function showAlive(mode){
// //window.location.href = 'alive.php?alivemode=' + mode;
//
//
// var oXmlHttp = zXmlHttp.createRequest();
//
//
// oXmlHttp.open("post", "alive.php", true);
// oXmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// oXmlHttp.onreadystatechange = function () {
......@@ -224,60 +224,152 @@ function sl(id) {
//}
function postCmd(formName,sendto){
var oXmlHttp = zXmlHttp.createRequest();
var sBody = getRequestBody(document.forms[formName]);
oXmlHttp.open("post", sendto, true);
oXmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
oXmlHttp.onreadystatechange = function () {
if (oXmlHttp.readyState == 4) {
if (oXmlHttp.status == 200) {
showData(oXmlHttp.responseText);
} else {
showNotice(oXmlHttp.statusText);
console.log('%c正在提交命令', 'background: blue; color: white; font-size: 16px;');
console.log('表单名称: ' + formName + ', 发送到: ' + sendto);
try {
var oXmlHttp = zXmlHttp.createRequest();
var formElement = document.forms[formName];
if (!formElement) {
console.error('找不到表单: ' + formName);
alert('找不到表单: ' + formName);
return;
}
var sBody = getRequestBody(formElement);
console.log('请求体: ' + sBody);
oXmlHttp.open("post", sendto, true);
oXmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
oXmlHttp.onreadystatechange = function () {
console.log('请求状态变化: ' + oXmlHttp.readyState);
if (oXmlHttp.readyState == 4) {
console.log('请求完成,状态码: ' + oXmlHttp.status);
if (oXmlHttp.status == 200) {
console.log('请求成功,响应长度: ' + oXmlHttp.responseText.length);
try {
showData(oXmlHttp.responseText);
} catch (e) {
console.error('处理响应时出错: ' + e.message);
alert('处理响应时出错: ' + e.message);
}
} else {
console.error('请求失败: ' + oXmlHttp.statusText);
showNotice(oXmlHttp.statusText);
}
}
}
console.log('发送请求...');
oXmlHttp.send(sBody);
console.log('请求已发送');
} catch (e) {
console.error('发送请求时出错: ' + e.message);
alert('发送请求时出错: ' + e.message);
}
oXmlHttp.send(sBody);
}
function showData(sdata){
shwData = sdata.parseJSON();
if(shwData['url']) {
window.location.href = shwData['url'];
}else if(!shwData['innerHTML']) {
$('error').innerHTML=sdata;
//window.location.href = 'index.php';
}else{
sDv = shwData['value'];
for(var id in sDv){
if($(id)!=null){
$(id).value = sDv[id];
console.log('%c正在处理响应数据', 'background: green; color: white; font-size: 16px;');
try {
// 尝试解析 JSON
console.log('响应数据片段: ' + sdata.substring(0, 100) + '...');
shwData = sdata.parseJSON();
console.log('解析后的数据类型: ' + typeof(shwData));
// 检查是否需要重定向
if(shwData['url']) {
console.log('需要重定向到: ' + shwData['url']);
window.location.href = shwData['url'];
} else if(!shwData['innerHTML']) {
console.log('没有 innerHTML 属性,显示原始数据');
if($('error')) {
$('error').innerHTML = sdata;
} else {
console.error('error 元素不存在');
alert('错误: ' + sdata);
}
}
sDi = shwData['innerHTML'];
for(var id in sDi){
if($(id)!=null){
if(sDi['id'] !== ''){
$(id).innerHTML = sDi[id];
}else{
$(id).innerHTML = '';
} else {
console.log('处理 innerHTML 和其他属性');
// 处理 value 属性
if(shwData['value']) {
sDv = shwData['value'];
console.log('value 属性的键数量: ' + Object.keys(sDv).length);
for(var id in sDv){
if($(id)!=null){
console.log('设置 ' + id + ' 的 value 为: ' + sDv[id]);
$(id).value = sDv[id];
} else {
console.warn('元素 ' + id + ' 不存在,无法设置 value');
}
}
}
}
sDd = shwData['display'];
for(var id in sDd){
if($(id)!=null){
$(id).style.display = sDd[id];
// 处理 innerHTML 属性
if(shwData['innerHTML']) {
sDi = shwData['innerHTML'];
console.log('innerHTML 属性的键数量: ' + Object.keys(sDi).length);
for(var id in sDi){
if($(id)!=null){
if(sDi[id] !== ''){
console.log('设置 ' + id + ' 的 innerHTML,长度: ' + sDi[id].length);
$(id).innerHTML = sDi[id];
} else {
console.log('清空 ' + id + ' 的 innerHTML');
$(id).innerHTML = '';
}
} else {
console.warn('元素 ' + id + ' 不存在,无法设置 innerHTML');
}
}
}
// 处理 display 属性
if(shwData['display']) {
sDd = shwData['display'];
console.log('display 属性的键数量: ' + Object.keys(sDd).length);
for(var id in sDd){
if($(id)!=null){
console.log('设置 ' + id + ' 的 display 为: ' + sDd[id]);
$(id).style.display = sDd[id];
} else {
console.warn('元素 ' + id + ' 不存在,无法设置 display');
}
}
}
}
}
if(shwData['timer'] && typeof(timerid)=='undefined'){
demiSecTimerStarter(shwData['timer']);
}
if ($('HsUipfcGhU')) //ˢ��ҳ����
{
window.location.reload();
// 处理计时器
if(shwData['timer'] && typeof(timerid)=='undefined'){
console.log('启动计时器: ' + shwData['timer']);
demiSecTimerStarter(shwData['timer']);
}
// 处理页面刷新
if ($('HsUipfcGhU')) {
console.log('检测到页面刷新标记,即将刷新页面');
window.location.reload();
}
console.log('响应数据处理完成');
} catch (e) {
console.error('处理响应数据时出错: ' + e.message);
console.error('原始数据: ' + sdata);
alert('处理响应数据时出错: ' + e.message);
// 尝试显示原始数据
if($('error')) {
$('error').innerHTML = '<div style="color: red; background-color: yellow; padding: 10px; border: 2px solid black;">错误: ' + e.message + '<br>原始数据: ' + sdata + '</div>';
}
}
}
......@@ -315,7 +407,7 @@ function showChatdata(jsonchat) {
newchat += chatdata['msg'][cid];
}
$('chatlist').innerHTML = newchat + $('chatlist').innerHTML;
}
}
}
function openShutManager(oSourceObj,oTargetObj,shutAble,oOpenTip,oShutTip){
......@@ -327,12 +419,12 @@ function openShutManager(oSourceObj,oTargetObj,shutAble,oOpenTip,oShutTip){
if(shutAble) return;
targetObj.style.display="none";
if(openTip && shutTip){
sourceObj.innerHTML = shutTip;
sourceObj.innerHTML = shutTip;
}
} else {
targetObj.style.display="block";
if(openTip && shutTip){
sourceObj.innerHTML = openTip;
sourceObj.innerHTML = openTip;
}
}
}
......
......@@ -7,20 +7,20 @@ if (! defined('IN_GAME')) {
/**
* 处理测试物品
* 这些物品主要用于测试游戏功能
*
*
* @param int $itmn 物品在物品栏中的位置
* @param array &$data 玩家数据
*/
function item_test($itmn, &$data) {
global $log, $db, $tablepre, $now, $pid, $event_bgm, $cmd;
extract($data, EXTR_REFS);
$itm = & ${'itm' . $itmn};
$itmk = & ${'itmk' . $itmn};
$itme = & ${'itme' . $itmn};
$itms = & ${'itms' . $itmn};
$itmsk = & ${'itmsk' . $itmn};
if ($itm == 'NPC战斗测试仪') {
include_once GAME_ROOT.'./include/game/revcombat.func.php';
$pa = fetch_playerdata_by_pid(1);
......@@ -42,6 +42,10 @@ function item_test($itmn, &$data) {
//???
$clbpara['dialogue'] = 'testingDialog';
//$clbpara['noskip_dialogue'] = 1;
} elseif ($itm == '对话选择测试器') {
// 带选择的对话测试
$clbpara['dialogue'] = 'choiceTestingDialog';
$clbpara['noskip_dialogue'] = 1; // 设置为不可跳过的对话
} elseif ($itm == '事件BGM替换器') {
// 这是一个触发事件BGM的案例,只要输入$clbpara['event_bgmbook'] = Array('事件曲集名'); 即可将当前曲集替换为特殊事件BGM
// 特殊事件曲集'event_bgmbook'的优先级高于地图曲集'pls_bgmbook',前者存在时后者不会生效
......@@ -219,7 +223,7 @@ function item_test($itmn, &$data) {
}
$itms--;
}
else
else
{
$log .= '这件长得很像猫的东西该怎么用呢?<br>';
}
......
<dialog id="dialogue" style="width: 460px; max-width: 90%;max-height: 80%;">
<script src="include/dialogue.js?v=<!--{eval time();}-->"></script>
<p><center>
<!-- 当前阅读页面 -->
<div id="dmarkpage" style="display: none;">0</div>
<!-- 对话框尾页 -->
<!--{eval $endpage = count($dialogues[$dialogue_id])-1;}-->
<!--{eval $maxdkey = $endpage + 1;}-->
<div id="dendpage" style="display: none;">$endpage</div>
<!-- 对白分段显示 -->
......@@ -13,7 +15,7 @@
<table>
<tr>
<!-- 带头像对白 -->
<!--{if isset($dialogue_icon[$dialogue_id][$dkey])}-->
<!--{if isset($dialogue_icon[$dialogue_id][$dkey])}-->
<td>
<img style="width:140px;height:80px;" src="$dialogue_icon[$dialogue_id][$dkey]">
</td>
......@@ -25,7 +27,7 @@
<td class="ach-cont" style="width:320px;height:80px;text-align: center; padding: 3% 6%;">
$dinfo
</td>
<!--{/if}-->
<!--{/if}-->
</tr>
</table>
<br>
......@@ -35,22 +37,25 @@
<!--{if (($dkey <= ($endpage-1)) || (isset($dialogue_branch[$dialogue_id])))}-->
<input type="button" class="cmdbutton" id="p" value="[P]下一页" onclick="changePages('d',1);">
<!--{elseif isset($dialogue_end[$dialogue_id])}-->
$dialogue_end[$dialogue_id]
$dialogue_end[$dialogue_id]
<!--{/if}-->
</div>
<!--{/loop}-->
<!-- 选择肢显示 -->
<!--{if isset($dialogue_branch[$dialogue_id])}-->
<div id="d{$maxdkey}" style="display: none;">
<table border="0" style="text-align: center;"><tr><td style="width:280px;height:80px; text-align: center; padding: 3% 6%;">
<div id="d{$maxdkey}" style="display: none;" class="ach_box">
<table border="0" style="text-align: center;"><tr><td style="width:320px;height:80px; text-align: center; padding: 3% 6%;">
<div style="margin-bottom: 10px;">请选择:</div>
<!--{loop $dialogue_branch[$dialogue_id] $bkey $binfo}-->
$binfo
<input type="button" class="cmdbutton" style="margin: 5px; display: block; width: 200px;" value="$binfo" onclick="handleDialogueChoice('{$dialogue_id}', '{$bkey}'); return false;">
<!--{/loop}-->
</td></tr></table>
</div>
<!--{/if}-->
<!-- 调试信息已移除 -->
</center></p>
<!--{if (isset($dialogue_branch[$dialogue_id]) || isset($dialogue_end[$dialogue_id]))}-->
<img class="dialog-background" src="img/profile.gif" onclick="">
......
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