Rindro-Sqr/Base/_Tool/Script_Class.nut

599 lines
20 KiB
Plaintext

/*
文件名:Script_Class.nut
路径:Base/_Tool/Script_Class.nut
创建日期:2024-10-21 14:49
文件用途:PVF读取类
*/
class BlobEx extends blob {
constructor(BaseBlob) {
blob.constructor(BaseBlob.len());
writeblob(BaseBlob);
}
function writeblob(B) {
blob.writeblob(B);
seek(0);
}
function GetUShort() {
return readn('s');
}
function GetShort() {
return readn('w');
}
function GetInt() {
local CurTPos = tell();
local Ret = charPtrToInt([this[CurTPos], this[CurTPos + 1], this[CurTPos + 2], this[CurTPos + 3]]);
seek(4, 'c');
return Ret;
}
function Get256() {
local Buf = readn('c');
return (256.0 + Buf.tofloat()) % 256.0;
}
function GetFloat() {
return readn('f');
}
function GetString(count) {
local MBuf = Memory.alloc(count);
local BlobBuf = readblob(count);
local arr = [];
foreach(value in BlobBuf) {
arr.append(value);
}
MBuf.writeByteArray(arr);
return MBuf.readUtf8String(count);
}
}
Rindro_Script_Bin_Data <- [];
class Rindro_Script {
function Get_Ani_Flip_Type(data) {
switch (data) {
case 1:
return "HORIZON";
case 2:
return "VERTICAL";
case 3:
return "ALL";
default:
return "";
}
}
function Get_Ani_Effect_Type(data) {
switch (data) {
case 0:
return "NONE";
case 1:
return "DODGE";
case 2:
return "LINEARDODGE";
case 3:
return "DARK";
case 4:
return "XOR";
case 5:
return "MONOCHROME";
case 6:
return "SPACEDISTORT";
default:
return "";
}
}
function Get_Ani_Damage_Type(data) {
switch (data) {
case 0:
return "NORMAL";
case 1:
return "SUPERARMOR";
case 2:
return "UNBREAKABLE";
default:
return "";
}
}
function Get_Ani_Flag(data) {
switch (data) {
case 0:
return "LOOP";
case 1:
return "SHADOW";
case 3:
return "COORD";
case 7:
return "IMAGE_RATE";
case 8:
return "IMAGE_ROTATE";
case 9:
return "RGBA";
case 10:
return "INTERPOLATION";
case 11:
return "GRAPHIC_EFFECT";
case 12:
return "DELAY";
case 13:
return "DAMAGE_TYPE";
case 14:
return "DAMAGE_BOX";
case 15:
return "ATTACK_BOX";
case 16:
return "PLAY_SOUND";
case 17:
return "PRELOAD";
case 18:
return "SPECTRUM";
case 23:
return "SET_FLAG";
case 24:
return "FLIP_TYPE";
case 25:
return "LOOP_START";
case 26:
return "LOOP_END";
case 27:
return "CLIP";
case 28:
return "OPERATION";
default:
return "";
}
}
function endswith(Str, cmp) {
local len = cmp.len();
local EndStr = Str.slice(-len);
if (EndStr == cmp)
return true;
return false;
}
function InitLoad_String() {
if (getroottable().rawin("RindroLoadStringTable")) return;
getroottable().RindroLoadStringTable <- {};
local N_String = R_Utils.GetScriptFileReader("n_string.lst");
if (N_String) {
local IO = Sq_Point2Blob(L_sq_P2I(N_String.Buffer.C_Object), N_String.Size);
local i = 2;
while (i< N_String.Size) {
if ((N_String.Size - i) >= 10) {
IO.seek(i + 6); //内容指示位
local FindKey = IO.readn('i');
local Key = Rindro_Script.GetBinString(FindKey);
if (Key) {
local StrFilePath = Key.tolower();
local StrFile = R_Utils.GetScriptFileReader(StrFilePath, 10240000);
if (StrFile) {
local StrBuffer = StrFile.Buffer.readUtf8String(StrFile.Size);
local StrArr = split(StrBuffer, "\r\n");
foreach(index, strobj in StrArr) {
if (strobj.find(">") != null) {
local strobjarr = split(strobj, ">");
if (strobjarr.len() > 1) {
getroottable().RindroLoadStringTable.rawset(strobjarr[0], Sq_ConvertWideChar(strobjarr[1], "big5"));
}
}
}
}
}
} else break;
i += 10;
}
}
}
function GetBin() {
local BinFile = R_Utils.GetScriptFileReader("stringtable.bin", 40960000);
if (BinFile) {
local Ro = Sq_Point2Blob(L_sq_P2I(BinFile.Buffer.C_Object), BinFile.Size);
Ro = BlobEx(Ro.readblob(Ro.len()));
local Count = Ro.readn('i');
local CurrentIndex = 0;
for (local i = 0; i< Count; i++) {
Ro.seek(CurrentIndex * 4 + 4);
local StartPos = Ro.readn('i');
local EndPos = Ro.readn('i');
local Len = EndPos - StartPos;
Ro.seek(StartPos + 4);
if (Len > 0) {
local Str = Ro.GetString(Len);
Rindro_Script_Bin_Data.append(Str);
}
CurrentIndex++;
}
}
}
function GetBinString(Index) {
if (Index< Rindro_Script_Bin_Data.len()) return Rindro_Script_Bin_Data[Index];
return "";
}
function GetLoadString(Key) {
if (getroottable().RindroLoadStringTable.rawin(Key)) return getroottable().RindroLoadStringTable[Key];
else return "";
}
function UnpackData(IO, i) {
local out = "";
IO.seek(i); //内容指示位
local currentByte = IO.readn('c'); //内容指示位
local after = IO.readn('i');
switch (currentByte) {
case 10: {
IO.seek(i - 4);
local Before = IO.readn('i');
local Buf = Rindro_Script.GetBinString(after);
if (!Buf) {
Buf = "";
} else {
Buf = "<" + Before + "::" + Buf + "`" + Rindro_Script.GetLoadString(Buf) + "`>";
}
Buf = Buf + "\r\n";
out += Buf;
break;
}
case 2: {
out += after + '\t';
break;
}
case 4: {
local Bbuf = blob(4);
Bbuf.writen(after, 'i');
Bbuf.seek(0);
local Buf = Bbuf.readn('f');
out += after + '\t';
break;
}
case 6:
case 8:
case 7:
case 5: {
local Buf = Rindro_Script.GetBinString(after);
if (!Buf) Buf = "";
return Buf;
}
case 9: {
IO.seek(i + 6);
local Before = IO.readn('i');
local Buf = Rindro_Script.GetBinString(Before);
out += Rindro_Script.GetLoadString(Buf);
}
default:
out += "";
break;
}
return out;
}
function ReadEquipment(ReadObject) {
local EquipmentAtt = {};
if (ReadObject.Size >= 7) {
//创建Blob对象
local IO = Sq_Point2Blob(L_sq_P2I(ReadObject.Buffer.C_Object), ReadObject.Size);
//以5为单步从第二位开始遍历字节
local i = 2;
while (true) {
if (i< ReadObject.Size && ReadObject.Size - i >= 5) {
local str = Rindro_Script.UnpackData(IO, i);
i += 5;
//名称
if (str == "[name]") {
local RealKey = str.slice(1, str.len() - 1);
EquipmentAtt[RealKey] <- Rindro_Script.UnpackData(IO, i);
i += 5;
}
//装备类型
else if (str == "[equipment type]") {
local Buf = Rindro_Script.UnpackData(IO, i);
EquipmentAtt["equipment_type"] <- Buf.slice(1, -1);
i += 5;
}
//称号动画
else if (str == "[custom animation]") {
local Buf = Rindro_Script.UnpackData(IO, i).tolower();
EquipmentAtt["custom_animation"] <- Buf;
i += 5;
}
//光环生成效果
else if (str == "[aurora graphic effects]") {
EquipmentAtt["Aurora"] <- {};
EquipmentAtt["Aurora"].Back <- [];
EquipmentAtt["Aurora"].Front <- [];
local Count = Rindro_Script.UnpackData(IO, i).tointeger() - 9;
i += 5;
for (local z = 0; z< Count; z++) {
local Layer = Rindro_Script.UnpackData(IO, i).tointeger() - 9;
i += 5;
local Path = Rindro_Script.UnpackData(IO, i).tolower();
i += 5;
if (Layer == 0) EquipmentAtt["Aurora"].Back.append(Path);
if (Layer == 1) EquipmentAtt["Aurora"].Front.append(Path);
}
i += 5;
}
//Ani
else if (str == "[animation job]") {
local Job = Rindro_Script.UnpackData(IO, i).slice(1, -1);
local SpacePos = Job.find(" ");
if (SpacePos) {
Job = Job.slice(0, SpacePos) + Job.slice(SpacePos + 1);
}
i += 5;
EquipmentAtt["Ani_" + Job] <- {};
i += 5;
local Index1 = Rindro_Script.UnpackData(IO, i).tointeger() - 9;
i += 5;
local Index2 = Rindro_Script.UnpackData(IO, i).tointeger() - 9;
i += 5;
EquipmentAtt["Ani_" + Job].variation <- [Index1, Index2];
EquipmentAtt["Ani_" + Job].layer_variation <- [];
while (true) {
try {
local Ret = Rindro_Script.UnpackData(IO, i);
i += 5;
if (Ret == "[animation job]" || (Rindro_Script.endswith(Ret, "]") && Ret != "[equipment ani script]" && Ret != "[layer variation]")) {
i -= 5;
break;
} else if (Ret == "[layer variation]") {
local InfoBuf = {};
InfoBuf.Zorder <- Rindro_Script.UnpackData(IO, i).tointeger() - 9;
i += 5;
InfoBuf.Path <- Rindro_Script.UnpackData(IO, i);
i += 5;
EquipmentAtt["Ani_" + Job].layer_variation.append(InfoBuf);
}
} catch (exception) {
break;
}
}
}
} else break;
}
}
return EquipmentAtt;
}
function ReadAnimation(ReadObject) {
local Ro = Sq_Point2Blob(L_sq_P2I(ReadObject.Buffer.C_Object), ReadObject.Size);
Ro = BlobEx(Ro.readblob(Ro.len()));
local AniObject = {
Img_List = [],
Frame = [],
Flag = {}
};
local Frame_Max = Ro.readn('s');
local Img_Count = Ro.readn('s');
//Img的路径读取 存入数组
for (local index = 0; index< Img_Count; index++) {
local Buf = Ro.readn('i');
local ImgPath = Ro.GetString(Buf);
//有可能Img有空路径
AniObject.Img_List.append(ImgPath);
}
//Ani头部标签数量
local Ani_H_Item_Count = Ro.readn('s');
//处理标签
for (local index = 0; index< Ani_H_Item_Count; index++) {
//标签类型
local Type = Ro.readn('s');
switch (Type) {
case 0:
case 1: {
local Key = Rindro_Script.Get_Ani_Flag(Type);
local Value = Ro.readn('c');
AniObject.Flag.rawset(Key, Value);
break;
}
case 3:
case 28: {
local Key = Rindro_Script.Get_Ani_Flag(Type);
local Value = Ro.readn('s');
AniObject.Flag.rawset(Key, Value);
break;
}
case 18:
// print("残影解析");
//此处无解析 暂时先保证运行 残影功能暂时用不上
Ro.readn('c');
Ro.readn('i');
Ro.readn('i');
Ro.readn('i');
Ro.Get256();
Ro.Get256();
Ro.Get256();
Ro.Get256();
Ro.readn('s');
break;
default:
break;
}
}
//读取每一个Img
for (local index = 0; index< Frame_Max; index++) {
//帧结构体对象
local FrameObject = {
AttackBox = [],
DamageBox = [],
Flag = {},
};
//碰撞框项目数量
local Ani_Box_Item_Count = Ro.readn('s');
for (local _i = 0; _i< Ani_Box_Item_Count; _i++) {
local Box_Type = Ro.readn('s');
local D_Box_b = [];
for (local _k = 0; _k< 6; _k++) {
D_Box_b.append(Ro.readn('i'));
}
if (Box_Type == 15) {
FrameObject.AttackBox.append(D_Box_b);
} else {
FrameObject.DamageBox.append(D_Box_b);
}
// //0是攻击框 1是受击框
// FrameObject.Box.rawset(15 - Box_Type, D_Box_b);
}
//调用的第几个Img
local Index_Buf = Ro.GetShort();
//如果等于-1说明是img路径为空
if (Index_Buf != 65535) {
FrameObject.Img_Path <- AniObject.Img_List[Index_Buf].tolower();
//Img中的PNG下标
FrameObject.Img_Index <- Ro.readn('s');
} else {
FrameObject.Img_Path <- "";
FrameObject.Img_Index <- 0;
}
//坐标
FrameObject.Pos <- {
x = Ro.readn('i'),
y = Ro.readn('i'),
};
//Img中的项目数量
local Img_Flag_Count = Ro.readn('s');
for (local _o = 0; _o< Img_Flag_Count; _o++) {
local Img_Flag_Type = Ro.readn('s');
local Key;
local Value;
switch (Img_Flag_Type) {
case 0:
case 1:
case 10:
Key = Rindro_Script.Get_Ani_Flag(Img_Flag_Type);
Value = Ro.readn('c');
FrameObject.Flag.rawset(Key, Value);
break;
case 3:
Key = "COORD";
Value = Ro.readn('s');
FrameObject.Flag.rawset(Key, Value);
break;
case 17:
Key = "PRELOAD";
Value = 1;
FrameObject.Flag.rawset(Key, Value);
break;
case 7:
Key = "IMAGE_RATE";
Value = {
x = Ro.GetFloat(),
y = Ro.GetFloat()
};
FrameObject.Flag.rawset(Key, Value);
break;
case 8:
Key = "IMAGE_ROTATE";
Value = Ro.GetFloat();
FrameObject.Flag.rawset(Key, Value);
break;
case 9:
Key = "RGBA";
Value = [
Ro.Get256(),
Ro.Get256(),
Ro.Get256(),
Ro.Get256(),
];
FrameObject.Flag.rawset(Key, Value);
break;
case 11:
local Effect_Type = Ro.readn('s');
Key = "GRAPHIC_EFFECT_" + Rindro_Script.Get_Ani_Effect_Type(Effect_Type);
switch (Effect_Type) {
case 5:
Value = [Ro.Get256(), Ro.Get256(), Ro.Get256()];
break;
case 6:
Value = [Ro.GetShort(), Ro.GetShort()];
break;
}
FrameObject.Flag.rawset(Key, Value);
break;
case 12:
Value = Ro.readn('i');
FrameObject.Delay <- Value;
break;
case 13:
Key = "DAMAGE_TYPE";
Value = Rindro_Script.Get_Ani_Damage_Type(Ro.readn('s'));
FrameObject.Flag.rawset(Key, Value);
break;
case 16:
local SoundTempSize = Ro.readn('i');
Key = "PLAY_SOUND";
Value = Ro.GetString(SoundTempSize);
FrameObject.Flag.rawset(Key, Value);
break;
case 23:
Key = "SET_FLAG";
Value = Ro.readn('i');
FrameObject.Flag.rawset(Key, Value);
break;
case 24:
Key = "FLIP_TYPE";
Value = Rindro_Script.Get_Ani_Flip_Type(Ro.readn('s'));
FrameObject.Flag.rawset(Key, Value);
break;
case 25:
Key = "LOOP_START";
FrameObject.Flag.rawset(Key, 1);
break;
case 26:
Key = "LOOP_END";
Value = Ro.readn('i');
FrameObject.Flag.rawset(Key, Value);
break;
case 27:
Key = "CLIP";
Value = [
Ro.GetShort(),
Ro.GetShort(),
Ro.GetShort(),
Ro.GetShort(),
];
FrameObject.Flag.rawset(Key, Value);
break;
default:
break;
}
}
//每一帧都是一个结构体 存入数组中
AniObject.Frame.append(FrameObject);
}
return AniObject;
}
}
Rindro_Script.GetBin();
Rindro_Script.InitLoad_String();