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;
......
This diff is collapsed.
......@@ -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,7 +192,10 @@ 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>";
}
......
......@@ -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;
}
......@@ -224,61 +224,153 @@ function sl(id) {
//}
function postCmd(formName,sendto){
console.log('%c正在提交命令', 'background: blue; color: white; font-size: 16px;');
console.log('表单名称: ' + formName + ', 发送到: ' + sendto);
try {
var oXmlHttp = zXmlHttp.createRequest();
var sBody = getRequestBody(document.forms[formName]);
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);
}
}
function showData(sdata){
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']) {
$('error').innerHTML=sdata;
//window.location.href = 'index.php';
}else{
} else if(!shwData['innerHTML']) {
console.log('没有 innerHTML 属性,显示原始数据');
if($('error')) {
$('error').innerHTML = sdata;
} else {
console.error('error 元素不存在');
alert('错误: ' + sdata);
}
} 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');
}
}
}
// 处理 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'] !== ''){
if(sDi[id] !== ''){
console.log('设置 ' + id + ' 的 innerHTML,长度: ' + sDi[id].length);
$(id).innerHTML = sDi[id];
}else{
} 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'){
console.log('启动计时器: ' + shwData['timer']);
demiSecTimerStarter(shwData['timer']);
}
if ($('HsUipfcGhU')) //ˢ��ҳ����
{
// 处理页面刷新
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>';
}
}
}
var refchat = null;
......
......@@ -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',前者存在时后者不会生效
......
<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>
<!-- 对白分段显示 -->
......@@ -42,15 +44,18 @@
<!-- 选择肢显示 -->
<!--{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