50指令翻译

需配合KA以前编写的“kdef转lua脚本的工具”。该工具可以将原版的指令转为lua脚本,一般来说可以有利于阅读理解,如果框架中有完整指令脚本支持,也能直接执行。但其中的50指令部分只是简单转换了,仍旧难以理解。

新增加的工具可以将这部分50指令转为正常的程序格式,制作者也可以自己修改源码和配置,应该能转成可以直接执行的格式。

源码在:https://github.com/scarsty/kys-t … %E6%AB%92/abcd/trans50

一个转换范例:

转换前的指令:

if CheckRoleSexual(256) == true then goto label0 end;
::label2::
   instruct_50e(8, 0, 7236, 400, 0, 0, 0);
   instruct_50e(34, 0, 15, 60, 285, 25, 0);
   instruct_50e(33, 0, 400, 20, 65, 26211, 0);
   instruct_50e(0, 1, 7237, 0, 0, 0, 0);
::label1::
   instruct_50e(3, 0, 2, 1005, 1002, 100, 0);
   instruct_50e(3, 0, 0, 1005, 1005, 2000, 0);
   instruct_50e(32, 0, 1005, 4, 0, 0, 0);
   instruct_50e(8, 1, 1, 400, 0, 0, 0);
   instruct_50e(3, 0, 0, 1, 1, 1, 0);
   instruct_50e(3, 0, 0, 1002, 1002, 1, 0);
   instruct_50e(4, 0, 0, 1002, 4, 0, 0);
   if CheckRoleSexual(256) == true then goto label1 end;
   instruct_50e(34, 0, 80, 95, 150, 83, 0);
   instruct_50e(39, 0, 4, 1100, 100, 85, 100);
   instruct_50e(4, 0, 2, 100, 0, 0, 0);
   if CheckRoleSexual(256) == true then goto label2 end;

转换后的指令:

::label2::
x[400] = "你為什么會選擇進入這個世界?";        --instruct_50e(8, 0, 7236, 400, 0, 0, 0);
DrawRect(15, 60, 285, 25);        --instruct_50e(34, 0, 15, 60, 285, 25, 0);
DrawString(x[400], 20, 65, 26211);        --instruct_50e(33, 0, 400, 20, 65, 26211, 0);
x[1] = 7237;        --instruct_50e(0, 1, 7237, 0, 0, 0, 0);
::label1::
x[1005] = x[1002] * 100;        --instruct_50e(3, 0, 2, 1005, 1002, 100, 0);
x[1005] = x[1005] + 2000;        --instruct_50e(3, 0, 0, 1005, 1005, 2000, 0);
temp = x[1005];        --instruct_50e(32, 0, 1005, 4, 0, 0, 0);
x[temp] = talk(x[1]);        --instruct_50e(8, 1, 1, 400, 0, 0, 0);
x[1] = x[1] + 1;        --instruct_50e(3, 0, 0, 1, 1, 1, 0);
x[1002] = x[1002] + 1;        --instruct_50e(3, 0, 0, 1002, 1002, 1, 0);
if x[1002] < 4 then jump_flag = false; else jump_flag = true; end;        --instruct_50e(4, 0, 0, 1002, 4, 0, 0);
if jump_flag == true then goto label1 end;
DrawRect(80, 95, 150, 83);        --instruct_50e(34, 0, 80, 95, 150, 83, 0);
strs = {};
for i=1, 4 do
strs[i] = x[x[1100] + i - 1];
end
x[100] = menu(strs, #strs, 85, 100);        --instruct_50e(39, 0, 4, 1100, 100, 85, 100);
if x[100] == 0 then jump_flag = false; else jump_flag = true; end;        --instruct_50e(4, 0, 2, 100, 0, 0, 0);
if jump_flag == true then goto label2 end;

可以看出是执行了一个选菜单。

再进一步的转换可以得到:

repeat
x[400] = "你為什么會選擇進入這個世界?";        --instruct_50e(8, 0, 7236, 400, 0, 0, 0);
DrawRect(15, 60, 285, 25);        --instruct_50e(34, 0, 15, 60, 285, 25, 0);
DrawString(x[400], 20, 65, 26211);        --instruct_50e(33, 0, 400, 20, 65, 26211, 0);
x[1] = 7237;        --instruct_50e(0, 1, 7237, 0, 0, 0, 0);
repeat
x[1005] = x[1002] * 100;        --instruct_50e(3, 0, 2, 1005, 1002, 100, 0);
x[1005] = x[1005] + 2000;        --instruct_50e(3, 0, 0, 1005, 1005, 2000, 0);
x[x[1005]] = GetTalk(x[1]);        --instruct_50e(8, 1, 1, 400, 0, 0, 0);
x[1] = x[1] + 1;        --instruct_50e(3, 0, 0, 1, 1, 1, 0);
x[1002] = x[1002] + 1;        --instruct_50e(3, 0, 0, 1002, 1002, 1, 0);
until x[1002] >= 4
DrawRect(80, 95, 150, 83);        --instruct_50e(34, 0, 80, 95, 150, 83, 0);
strs = {};
for i=1, 4 do
strs[i] = x[x[1100 + i - 1]];
end
x[100] = menu(85, 100, strs, #strs);        --instruct_50e(39, 0, 4, 1100, 100, 85, 100);
until x[100] ~= 0

可以看出此时逻辑已经比较清楚了。

需注意转换结果中没有考虑x的变量空间连续。本垃圾分析这个连续的条件很少被用到,如遇到也可以手动修改。

代码可读性 += 1e-5

目前进一步的分析可以将代码更简化一些,例如以下跳转场景的例子,看起来似乎好了一些。

同时,也尝试用cifa取代lua。

instruct_50(26, 0, 0, 10590, 29, 200, 0);
instruct_50(26, 0, 0, 10588, 29, 201, 0);
instruct_50(26, 0, 0, 10586, 29, 202, 0);
instruct_50(24, 13, 200, 3, 201, 202, 203);
instruct_50(22, 3, 200, 203, 7, 204, 0);
instruct_50(3, 0, 2, 204, 204, -1, 0);
instruct_50(16, 5, 2, 200, 16, 204, 0);
instruct_50(16, 5, 2, 200, 44, 201, 0);
instruct_50(16, 5, 2, 200, 46, 202, 0);
instruct_50(22, 3, 200, 203, 8, 205, 0);
instruct_50(3, 0, 3, 206, 205, 100, 0);
instruct_50(3, 0, 4, 207, 205, 100, 0);
instruct_50(17, 1, 2, 200, 20, 208, 0);
instruct_50(17, 1, 2, 200, 22, 209, 0);
instruct_50(4, 0, 5, 208, 0, 0, 0);
if CheckJumpFlag() == true then goto label0 end;
   instruct_50(4, 0, 5, 209, 0, 0, 0);
   if CheckJumpFlag() == true then goto label1 end;
   instruct_50(16, 5, 2, 204, 48, 206, 0);
   instruct_50(16, 5, 2, 204, 50, 207, 0);
exit();
::label0::
::label1::
   instruct_50(16, 5, 2, 204, 28, 206, 0);
   instruct_50(16, 5, 2, 204, 30, 207, 0);
exit();

SetX50(200, getcurrentscene());
SetX50(201, getsceney());
SetX50(202, getscenex());
SetX50(203, GetS(GetX50(200), 3, GetX50(201), GetX50(202)));
SetX50(204, GetD(GetX50(200), GetX50(203), 7));
SetX50(204, GetX50(204) * -1);
SetSubmapInfo(GetX50(200), 16 / 2, GetX50(204));
SetSubmapInfo(GetX50(200), 44 / 2, GetX50(201));
SetSubmapInfo(GetX50(200), 46 / 2, GetX50(202));
SetX50(205, GetD(GetX50(200), GetX50(203), 8));
SetX50(206, GetX50(205) / 100);
SetX50(207, GetX50(205) % 100);
SetX50(208, GetSubmapInfo(GetX50(200), 20 / 2));
SetX50(209, GetSubmapInfo(GetX50(200), 22 / 2));
if (GetX50(208) <= 0 && GetX50(209) <= 0) {
   SetSubmapInfo(GetX50(204), 48 / 2, GetX50(206));
   SetSubmapInfo(GetX50(204), 50 / 2, GetX50(207));
   exit();
}
SetSubmapInfo(GetX50(204), 28 / 2, GetX50(206));
SetSubmapInfo(GetX50(204), 30 / 2, GetX50(207));

或许可以尝试借助llm写一个正经的转lua工具