📄 gscript.java
字号:
import java.io.*;
import java.util.*;
/**
* <p>Title: Script</p>
* <p>Description: Game Script</p>
* <p>Copyright: CoCoMo Copyright (c) 2006</p>
* <p>HTML: http://spaces.msn.com/j2medev
* <p>Company: 9you</p>
* @author 郭昉
* @version 1.3 Optimized
*/
public class GScript {
// 保留指令-------------------------------------------------------------------
static final byte RESERVE_IF_ID = -1; //IF
static final byte RESERVE_CALL_ID = -2; //CALL
static final byte RESERVE_RETURN_ID = -3; //RETURN
static final byte RESERVE_BREAK_ID = -4; //BREAK
static final byte RESERVE_LOADSCRIPT_ID = -5; //LOADSCRIPT
static final byte RESERVE_UNLOADSCRIPT_ID = -6; //UNLOADSCRIPT
// 终结符类型-------------------------------------------------------------------
static final byte T_IDENTIFER = 10; //标识符
static final byte T_INTEGER = 11; //整型
static final byte T_FLOAT = 12; //浮点型 (作保留用)
static final byte T_CHAR = 13; //字符型 (作保留用)
static final byte T_STRING = 14; //字符串型
static final byte T_TRUE = 15; //true
static final byte T_FALSE = 16; //false
static final byte T_SCRIPT = 17; //脚本型变量
// 操作符类型-------------------------------------------------------------------
static final byte O_EQ = 10; //等于
static final byte O_NE = 11; //不等于
static final byte O_LT = 12; //小于
static final byte O_GT = 13; //大于
static final byte O_LE = 14; //小于等于
static final byte O_GE = 15; //大于等于
// 数据段-------------------------------------------------------------------
public static byte[] m_variable; //变量列表
public static Vector m_string = new Vector(); //字符串存储区
// 指令段-------------------------------------------------------------------
public static short[][][] m_script; //脚本数据 格式:[脚本索引][指令索引][参数索引]
public static short[] m_param; //参数列表
// 断点数据 -------------------------------------------------------------------
static short[][] m_recursion; //断点列表 格式:[脚本索引][指令索引]
static byte m_recursionLevel; //断点索引
// 控制变量-------------------------------------------------------------------
static short m_curScript; //当前脚本索引
static short m_curIns; //当前指令索引
static boolean b_running; //脚本引擎控制
// 脚本文件 -------------------------------------------------------------------
static String m_file;
public GScript() {
}
//脚本运行前必须调用此函数
static void init(String file) {
try {
m_file = file;
//支持8级调用 (可修改)
m_recursion = new short[8][2];
m_recursionLevel = 0;
m_curScript = 0;
m_curIns = 0;
LoadScript(m_curScript, false);
//支持8个参数 (可修改)
m_param = new short[8];
b_running = true;
}
catch(Exception e) {
e.printStackTrace();
}
}
//读取文件头 isSkip为真跳过文件头读取
private static void readHead(DataInputStream in, boolean isSkip) {
try {
// 变量-------------------------------------------------------------------
int count = in.readShort();
if(isSkip) {
in.skip(count + 2); // Include Script Count
}
else {
m_variable = new byte[count];
for (int i = 0; i < count; i++) {
m_variable[i] = in.readByte();
}
// Script-------------------------------------------------------------------
count = in.readShort();
m_script = new short[count][][];
}
}
catch(Exception e) {
e.printStackTrace();
}
}
// -------------------------------------------------------------------
// SCRIPT PART
// -------------------------------------------------------------------
static void LoadScript(int sNo, boolean isSkip) {
try {
if(isSkip && m_script[sNo] != null) {
return;
}
DataInputStream in = new DataInputStream(m_file.getClass().getResourceAsStream(m_file));
// Head-------------------------------------------------------------------
readHead(in, isSkip);
// Skip-------------------------------------------------------------------
in.skip(sNo * 2);
int off = in.readShort();
in.skip(off);
// 指令-------------------------------------------------------------------
int count = in.readShort();
m_script[sNo] = new short[count][];
for (int i = 0; i < count; i++) {
int index = 0;
short id = in.readShort();
short paramCount = in.readByte();
if (id == RESERVE_IF_ID) { // If Statement
m_script[sNo][i] = new short[2 + paramCount * 5 + 1];
}
else {
m_script[sNo][i] = new short[2 + paramCount * 2];
}
m_script[sNo][i][index++] = id;
m_script[sNo][i][index++] = paramCount;
// 参数-------------------------------------------------------------------
for (int j = 0; j < paramCount; j++) {
if (id == RESERVE_IF_ID) { // If Statement
readTeminal(in, m_script[sNo][i], index);
index += 2;
m_script[sNo][i][index++] = in.readByte();
readTeminal(in, m_script[sNo][i], index);
index += 2;
}
else {
readTeminal(in, m_script[sNo][i], index);
index += 2;
}
}
if(id == RESERVE_IF_ID) {
m_script[sNo][i][index++] = in.readShort();
}
}
in.close();
in = null;
}
catch(Exception e) {
e.printStackTrace();
}
}
private static void UnLoadScript(int sNo) {
try {
int id, count, type, value;
if(m_script[sNo] == null) {
return;
}
for (int i = 0; i < m_script[sNo].length; i++) {
id = m_script[sNo][i][0];
if (id < 0) {
continue;
}
count = m_script[sNo][i][1];
for (int j = 0; j < count; j++) {
type = m_script[sNo][i][2 + j * 2];
if (type == T_CHAR || type == T_STRING) {
value = m_script[sNo][i][3 + j * 2];
m_string.setElementAt("", value);
}
}
}
m_script[sNo] = null;
}
catch(Exception e) {
e.printStackTrace();
}
}
//读取终结符
private static void readTeminal(DataInputStream in, short[] ins, int index) {
try {
byte type = in.readByte();
short value = 0;
switch (type) {
case T_IDENTIFER:
case T_INTEGER:
case T_FLOAT:
case T_SCRIPT:
value = in.readShort();
break;
case T_CHAR:
case T_STRING:
String str = "";
int count = in.readShort();
for(int i = 0; i < count; i++) {
str += in.readChar();
}
// String str = in.readUTF();
String test = null;
for(int i = 0; i < m_string.size(); i++) {
test = (String) m_string.elementAt(i);
if(test != null && test.equals("")) {
m_string.setElementAt(str, i);
value = (short) i;
test = null;
str = null;
ins[index++] = type;
ins[index++] = value;
return;
}
}
m_string.addElement(str);
value = (short) (m_string.size() - 1);
test = null;
str = null;
break;
case T_TRUE:
case T_FALSE:
value = in.readByte();
break;
}
ins[index++] = type;
ins[index++] = value;
}
catch (Exception e) {
e.printStackTrace();
}
}
//if语句
private static void ifStatement() {
int paramCount, t_leftType, t_leftValue, t_rightType, t_rightValue, o_type, skip_pos, skip;
paramCount = m_script[m_curScript][m_curIns][1];
for (int i = 0; i < paramCount; i++) {
t_leftType = m_script[m_curScript][m_curIns][2 + i * 5];
t_leftValue = m_script[m_curScript][m_curIns][2 + i * 5 + 1];
o_type = m_script[m_curScript][m_curIns][2 + i * 5 + 2];
t_rightType = m_script[m_curScript][m_curIns][2 + i * 5 + 3];
t_rightValue = m_script[m_curScript][m_curIns][2 + i * 5 + 4];
if(!isConditionTrue(t_leftType, t_leftValue, o_type, t_rightType, t_rightValue)) {
skip_pos = m_script[m_curScript][m_curIns].length - 1;
skip = m_script[m_curScript][m_curIns][skip_pos];
m_curIns += skip;
return;
}
}
}
private static boolean isConditionTrue(int l_type, int l_value, int o_type, int r_type, int r_value) {
if(l_type == T_IDENTIFER) {
l_value = m_variable[l_value];
}
if(r_type == T_IDENTIFER) {
r_value = m_variable[r_value];
}
switch (o_type) {
case O_EQ: //==
if(l_value == r_value) return true;
else return false;
case O_NE: //!=
if(l_value != r_value) return true;
else return false;
case O_LT: //<
if(l_value < r_value) return true;
else return false;
case O_GT: //>
if(l_value > r_value) return true;
else return false;
case O_LE: //<=
if(l_value <= r_value) return true;
else return false;
case O_GE: //>=
if(l_value >= r_value) return true;
else return false;
default:
return false;
}
}
// -------------------------------------------------------------------
// 消息部分
// -------------------------------------------------------------------
//运行指定脚本 sNo:脚本号
static void runScript(int sNo) {
b_running = true;
GScript.m_curScript = (short) sNo;
GScript.m_curIns = 0;
}
static void run() {
try {
while (b_running && m_curIns < m_script[m_curScript].length) {
runCommand();
}
}catch(Exception e) {
e.printStackTrace();
}
}
// -------------------------------------------------------------------
// 控制部分
// -------------------------------------------------------------------
static void stop() {
b_running = false;
}
static void turnOn() {
b_running = true;
}
private static void runCommand() {
try {
if (m_curIns < 0 || m_curIns >= m_script[m_curScript].length) {
return;
}
if(m_script[m_curScript] == null)
LoadScript(m_curScript, true);
//获取参数
int insID = m_script[m_curScript][m_curIns][0];
if(insID != RESERVE_IF_ID) {
int count = m_script[m_curScript][m_curIns][1];
int index = 3;
for(int i = 0; i < count; i++) {
m_param[i] = m_script[m_curScript][m_curIns][index];
index += 2;
}
}
// System.out.println("Command: " + insID); //调试用语句
// --------------------------------------------------------------------
// 系统指令
// --------------------------------------------------------------------
switch(insID) {
case RESERVE_CALL_ID:
callCommand();
LoadScript(m_curScript, true);
return;
case RESERVE_IF_ID:
ifStatement();
break;
case RESERVE_LOADSCRIPT_ID:
LoadScript(m_param[0], true);
break;
case RESERVE_UNLOADSCRIPT_ID:
UnLoadScript(m_param[0]);
break;
case RESERVE_BREAK_ID:
breakCommand();
break;
case RESERVE_RETURN_ID:
if(m_recursionLevel > 0) {
returnCommand();
}
else {
stop();
return;
}
break;
// -------------------------------------------------------------------
// 自定义指令
// -------------------------------------------------------------------
case 1: //Print
String str = (String) m_string.elementAt(m_param[0]);
Game.print(str);
break;
}
nextCommand();
}
catch(Exception e) {
e.printStackTrace();
}
}
private static void nextCommand()
{
try {
m_curIns++;
while (m_curIns == m_script[m_curScript].length) { //如果有调用 递归返回上级脚本
if (m_recursionLevel > 0) {
returnCommand();
}
else {
stop();
return;
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
private static void callCommand()
{
try
{
m_recursion[m_recursionLevel][0] = m_curScript;
m_recursion[m_recursionLevel][1] = m_curIns;
m_recursionLevel++;
m_curScript = m_param[0];
m_curIns = 0;
}
catch(Exception e)
{
e.printStackTrace();
}
}
private static void returnCommand()
{
try
{
m_recursionLevel--;
m_curScript = m_recursion[m_recursionLevel][0];
m_curIns = m_recursion[m_recursionLevel][1];
m_curIns++; //返回下一条指令
}
catch(Exception e)
{
e.printStackTrace();
}
}
private static void breakCommand()
{
try
{
m_recursionLevel = 0;
m_curIns = (short) m_script[m_curScript].length;
stop();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -