no message

This commit is contained in:
2025-11-08 12:21:06 +08:00
parent e195b0f168
commit 204151d95c
82 changed files with 151530 additions and 12 deletions

View File

@@ -0,0 +1,545 @@
/*
文件名:Animation_Class.nut
路径:Base/_Tool/Animation_Class.nut
创建日期:2024-10-21 16:57
文件用途:动画类
*/
class Rindro_Animation {
//Ani是否可用
IsUsability = true;
//当前帧数
CurrentFrameIndex = 0;
//当前帧时间
CurrentIndexT = 0;
//当前帧
CurrentFrame = null;
//Ani的标签
AnimationFlag = null;
//图片对象数组
PngList = null;
//帧对象数组
FrameList = null;
//附加选项
AdditionalOptions = null;
//角度
Angle = 0;
constructor(Data, ...) {
PngList = [];
FrameList = [];
//附加选项
if (vargc > 0) AdditionalOptions = vargv[0];
//初始化数据
InitData(Data);
}
function InitData(Data) {
local Buf;
if (type(Data) == "table") {
Buf = Data;
}
//从PVF数据加载
else if (type(Data) == "string") {
local ReadObject = R_Utils.GetScriptFileReader(Data);
if (ReadObject) {
Buf = Rindro_Script.ReadAnimation(ReadObject);
}
}
if (Buf) {
AnimationFlag = Buf.Flag;
FrameList = Buf.Frame;
foreach(FrameObj in FrameList) {
//如果有附加处理 格式化
if (AdditionalOptions && AdditionalOptions.rawin("ImgFormat")) FrameObj.Img_Path = AdditionalOptions["ImgFormat"](FrameObj.Img_Path);
local Png = Rindro_Image.Load(FrameObj.Img_Path);
// Png.Draw(-500, -500);
//如果有附加处理 坐标
if (AdditionalOptions && AdditionalOptions.rawin("Pos")) {
FrameObj.Pos.x += AdditionalOptions["Pos"].x;
FrameObj.Pos.y += AdditionalOptions["Pos"].y;
}
// Spritebuf.SetPosition(FrameObj.Pos);
PngList.append(Png);
}
} else {
AnimationFlag = {};
FrameList.append({
AttackBox = [],
DamageBox = [],
Delay = 800,
Flag = {},
Img_Index = 0,
Img_Path = "",
Pos = {
x = -248,
y = -331
}
})
// print(Data);
// print("创建Ani失败,找不到Ani数据");
}
}
//重置Ani
function Reset() {
IsUsability = true;
FlushFrame(0);
}
//获取当前帧信息
function GetCurrentFrameInfo() {
return FrameList[CurrentFrameIndex];
}
function FlushFrame(Index) {
if (PngList.len() <= 0) return;
//同步当前帧
CurrentFrameIndex = Index;
//当前帧更换为本帧
CurrentFrame = PngList[CurrentFrameIndex];
local FlagBuf = FrameList[CurrentFrameIndex].Flag;
//关键帧
if ("SET_FLAG" in FlagBuf) {
// if (StateMachine && StateMachine.State != -1) StateMachine.ChangeAniKeyFlag(FlagBuf.SET_FLAG);
}
//播放音效
if ("PLAY_SOUND" in FlagBuf) {
R_Utils.PlaySound(FlagBuf.PLAY_SOUND);
}
}
//绘制
function DrawFrame(X, Y) {
// local NowDrawPng = CurrentFrame;
if (FrameList.len() <= 0) return;
local FrameObj = FrameList[CurrentFrameIndex];
// printT(FrameObj);
//坐标偏移
local XOffset = FrameObj.Pos.x;
local YOffset = FrameObj.Pos.y;
//染色
local RGBA = sq_RGBA(255, 255, 255, 255);
if ("RGBA" in FrameObj.Flag) {
local Fbuf = FrameObj.Flag.RGBA;
RGBA = sq_RGBA(Fbuf[0].tointeger(), Fbuf[1].tointeger(), Fbuf[2].tointeger(), Fbuf[3].tointeger());
}
//缩放
local XRate = 1.0;
local YRate = 1.0;
if ("IMAGE_RATE" in FrameObj.Flag) {
local Fbuf = FrameObj.Flag.IMAGE_RATE;
XRate = Fbuf.x;
YRate = Fbuf.y;
}
//线性减淡
if ("GRAPHIC_EFFECT_LINEARDODGE" in FrameObj.Flag) {
L_sq_SetDrawImgModel(2, 0);
}
if (CurrentFrame) CurrentFrame.DrawExPng(FrameObj.Img_Index, X + XOffset, Y + YOffset, Angle, RGBA, XRate, YRate);
//线性减淡
if ("GRAPHIC_EFFECT_LINEARDODGE" in FrameObj.Flag) {
L_sq_ReleaseDrawImgModel();
}
}
function Draw(X, Y) {
//可用性检查
if (IsUsability) {
DrawFrame(X, Y);
//累加当前帧时间
CurrentIndexT += Rindro_Duration;
//当前帧时间 超过 当前帧延迟就需要切换帧了
if ("Delay" in FrameList[CurrentFrameIndex] && CurrentIndexT >= FrameList[CurrentFrameIndex].Delay) {
CurrentIndexT = 0;
//如果当前帧小于总帧数就切换
if (CurrentFrameIndex<(FrameList.len() - 1)) {
FlushFrame(CurrentFrameIndex + 1);
}
//说明播放完毕了
else {
//如果有循环
if ("LOOP" in AnimationFlag) {
FlushFrame(0);
}
//没有循环触发状态机回调
else {
//将不再可用
IsUsability = false;
}
}
}
}
}
function DrawIndex(X, Y, Index) {
// return;
if (IsUsability) {
FlushFrame(Index);
DrawFrame(X, Y);
}
}
}
//绘制角色类
class Rindro_Draw_Character {
//名字
Name = null;
//职业
Job = null;
//绘制体信息
DrawInfo = null;
//隐藏图层Map
HideMap = null;
ENUM_RINDRO_JOB_NAME = ["swordman", "fighter", "gunner", "mage", "priest", "atgunner", "thief", "atfighter", "atmage", "demonicswordman", "creatormage"];
ENUM_RINDRO_JOB_TITLE_HEIGHT = [
//男鬼剑士
{
x = -42,
y = -154
},
//女格斗
{
x = -42,
y = -140
},
//男神枪手
{
x = -44,
y = -168
},
//女魔法师
{
x = -46,
y = -126
},
//男圣职者
{
x = -46,
y = -166
},
//女神枪手
{
x = -42,
y = -156
},
//女暗夜使者
{
x = -44,
y = -154
},
//男格斗家
{
x = -45,
y = -160
},
//男魔法师
{
x = -45,
y = -140
},
//黑暗武士
{
x = -42,
y = -154
},
//缔造者
{
x = -46,
y = -126
},
];
ENUM_RINDRO_JOB_FACE_HEIGHT = [
//男鬼剑士
{
x = 11,
y = 111
},
//女格斗
{
x = 9,
y = 103
},
//男神枪手
{
x = 13,
y = 131
},
//女魔法师
{
x = 14,
y = 87
},
//男圣职者
{
x = 16,
y = 126
},
//女神枪手
{
x = 11,
y = 119
},
//女暗夜使者
{
x = 12,
y = 115
},
//男格斗家
{
x = 13,
y = 119
},
//男魔法师
{
x = 13,
y = 101
},
//黑暗武士
{
x = -42,
y = -154
},
//缔造者
{
x = -46,
y = -126
},
];
//获取角色AniBy装备
function GetCharacAniByEqu(Job, Equ, AniName) {
local AniList = [];
foreach(value in Equ) {
if (value > 0) {
local ListBuf = CreateEquipmentAni(value, Job, AniName);
AniList.extend(ListBuf);
}
}
local n = AniList.len();
for (local i = 0; i< n - 1; i++) {
for (local j = i + 1; j< n; j++) {
if (AniList[i].Layer > AniList[j].Layer) {
// 交换两个元素
local temp = AniList[i];
AniList[i] = AniList[j];
AniList[j] = temp;
}
}
}
return AniList;
}
function CreateEquipmentAni(Index, Job, AniName) {
local AniList = [];
//获取装备或时装的文件路径
local FilePath = R_Utils.GetEquPath(Index);
if (FilePath) {
local ReadObject = R_Utils.GetScriptFileReader("equipment/" + FilePath);
if (ReadObject) {
local Equ = Rindro_Script.ReadEquipment(ReadObject);
//职业名字
local JobName = ENUM_RINDRO_JOB_NAME[Job];
//没有装备类型
if (!(Equ.rawin("equipment_type"))) Equ.equipment_type <- "normal";
//光环单独处理 其他的在下面处理
if (Equ.equipment_type == "aurora avatar") {
foreach(Path in Equ.Aurora.Back) {
// local AniBuf = Rindro_Animation(Path);
AniList.append({
Ani = Path,
AniName = Path + Clock(),
Layer = -10000,
DrawType = "Native"
});
}
foreach(Path in Equ.Aurora.Front) {
// local AniBuf = Rindro_Animation(Path);
AniList.append({
Ani = Path,
AniName = Path + Clock(),
Layer = 10000,
DrawType = "Native"
});
}
}
//称号
else if (Equ.equipment_type == "title name") {
local PathBuf = "equipment/" + FilePath;
PathBuf = PathBuf.slice(0, R_Utils.String.FindLastSubstring(PathBuf, "/"));
local Path = PathBuf + "/" + Equ.custom_animation;
local Ao = {
Pos = ENUM_RINDRO_JOB_TITLE_HEIGHT[Job]
}
local AniBuf = Rindro_Animation(Path, Ao);
AniList.append({
Ani = AniBuf,
Layer = 10001,
});
}
//没有Ani 就那种透明时装
if (!(Equ.rawin("Ani_" + JobName))) return AniList;
//记录时装的隐藏图层值
if (Equ.rawin("hidelayer")) {
foreach(value in Equ["hidelayer"]) {
HideMap.rawset(value, true);
}
}
//读取Ani配置
local AniScript = Equ["Ani_" + JobName];
// printT(AniScript);
if (Equ.equipment_type == "skin avatar") {
local Path;
if (JobName.find("at") >= 0) {
Path = format("character/%s/atanimation/%s", JobName.slice(2), AniName);
} else Path = format("character/%s/animation/%s", JobName, AniName);
local Ao = {
ImgVariation = AniScript.variation,
ImgFormat = function(ImgPath) {
if (ImgVariation[0] > 0) {
local Pos = ImgPath.find("%04d");
ImgPath = ImgPath.slice(0, Pos) + "%02d%02d" + ImgPath.slice(Pos + 4);
return format(ImgPath, ImgVariation[0], ImgVariation[1]);
} else {
return format(ImgPath, ImgVariation[1]);
}
}
}
local AniBuf = Rindro_Animation(Path, Ao);
AniList.append({
Ani = AniBuf,
Layer = -1,
});
} else {
foreach(Info in AniScript.layer_variation) {
local PathBuf = "equipment/" + FilePath;
PathBuf = PathBuf.slice(0, R_Utils.String.FindLastSubstring(PathBuf, "/"));
local Path = PathBuf + "/" + Info.Path + "/" + AniName;
local Ao = {
ImgVariation = AniScript.variation,
ImgFormat = function(ImgPath) {
return format(ImgPath, ImgVariation[0], ImgVariation[1]);
}
}
local AniBuf = Rindro_Animation(Path, Ao);
AniList.append({
Ani = AniBuf,
Layer = Info.Zorder,
});
}
}
}
}
return AniList;
}
constructor(Job, EquipmentArr, Action, Name) {
HideMap = {};
DrawInfo = GetCharacAniByEqu(Job, EquipmentArr, Action);
this.Job = Job;
this.Name = Name;
}
function Draw(X, Y) {
foreach(AniInfo in DrawInfo) {
// print(AniInfo.Layer);
if (!HideMap.rawin(AniInfo.Layer)) {
if (!AniInfo.rawin("DrawType") || AniInfo["DrawType"] != "Native") {
AniInfo.Ani.Draw(X, Y);
} else {
Rindro_BaseToolClass.DrawAniEx(X, Y, AniInfo.Ani, AniInfo.AniName);
}
}
}
if (Name) {
L_sq_DrawCode(Name, 44 + X + ENUM_RINDRO_JOB_TITLE_HEIGHT[Job].x - (LenheartTextClass.GetStringLength(Name) / 2), Y + ENUM_RINDRO_JOB_TITLE_HEIGHT[Job].y + 24, sq_RGBA(255, 255, 255, 250), 1, 1);
}
}
function DrawFace(X, Y) {
//兼容模式
if (getroottable().PluginsCompatibilityModeCallBack){
return;
}
setClip(X, Y, X + 22, Y + 18); //开始裁切
foreach(AniInfo in DrawInfo) {
try {
AniInfo.Ani.DrawIndex(X + ENUM_RINDRO_JOB_FACE_HEIGHT[Job].x, Y + ENUM_RINDRO_JOB_FACE_HEIGHT[Job].y, 0);
} catch (exception) {
}
}
releaseClip(); //裁切结束
}
}
//鬼剑士
//601580026 101550559
// Sassq <- {};
// Sassq[0] <- Rindro_Draw_Character(0, [
// 601550071,
// 601560067,
// 601570062,
// 601500069,
// 601510068,
// 601540069,
// 601520061,
// 601530060,
// 601580026,
// 0,
// 27610,
// 26058
// ], "rest.ani", "鬼剑士-Kina")
// //格斗家
// Sassq[1] <- Rindro_Draw_Character(1, [26373, 102550540, 102560700, 102570504, 102520514, 102500742, 102510739, 102540664, 102580139, 102530474], "rest.ani", "Kina")
// //神枪手
// Sassq[2] <- Rindro_Draw_Character(2, [26373, 104550553, 104560725, 104570492, 104520541, 104500750, 104510913, 104540671, 104580148, 104530494], "rest.ani", "Kina")
// //魔法师
// Sassq[3] <- Rindro_Draw_Character(3, [26373, 106550521, 106560580, 106570446, 106520529, 106500603, 106510607, 106540583, 106580143, 106530461], "rest.ani", "Kina")
// //圣职者
// Sassq[4] <- Rindro_Draw_Character(4, [26373, 108550600, 108560591, 108570687, 108520580, 108500587, 108510590, 108540562, 108580138, 108530560], "rest.ani", "Kina")
// //女枪
// Sassq[5] <- Rindro_Draw_Character(5, [26373, 105550431, 105560424, 105570386, 105520415, 105500424, 105510429, 105540408, 105580144, 105530361], "rest.ani", "Kina")
// //暗夜
// Sassq[6] <- Rindro_Draw_Character(6, [26373, 109550385, 109560393, 109570369, 109520406, 109500402, 109510414, 109540389, 109580134, 109530355], "rest.ani", "Kina")
// //男格斗
// Sassq[7] <- Rindro_Draw_Character(7, [26373, 103550302, 103560311, 103570274, 103520297, 103500297, 103510301, 103540284, 103580128, 103530246], "rest.ani", "Kina")
// //男法
// Sassq[8] <- Rindro_Draw_Character(8, [26373, 107550220, 107560223, 107570188, 107520224, 107500233, 107510231, 107540209, 107580129, 107530192], "rest.ani", "Kina")

View File

@@ -0,0 +1,516 @@
/*
文件名:BaseTool_Class.nut
路径:Base/_Tool/BaseTool_Class.nut
创建日期:2024-08-06 23:49
文件用途:基础工具类
*/
function printT(T) {
Sq_OutPutTable(Json.Encode(T));
}
//Json类
class Json {
function Encode(Table) {
local JsonObj = JSONEncoder();
return JsonObj.encode(Table);
local Size = Table.len();
local Pos = 0;
local Str = "{";
foreach(Key, Value in Table) {
++Pos;
Str += "\"";
Str += Key.tostring();
Str += "\"";
Str += ":";
if (typeof(Value) == "string") {
Str += "\"";
Str += Value;
Str += "\"";
} else if (typeof(Value) == "table") {
Str += Json.Encode(Value);
} else if (typeof(Value) == "array") {
Str += "[";
foreach(ArrObj in Value) {
if (typeof(ArrObj) == "table") Str += Json.Encode(Value);
else {
Str += ArrObj;
Str += ",";
}
}
Str = Str.slice(0, Str.len() - 1);
Str += "]";
} else Str += Value;
if (Pos != Size) Str += ",";
}
Str += "}";
return Str;
}
function Decode(Str) {
// Str = L_sq_DecondeJson(Str);
// local Str = "local _M = " + Str + ";\n return _M;\n";
// local Func = compilestring(Str);
// return Func();
local JsonObj = JSONParser();
return JsonObj.parse(Str);
}
}
//Key 键盘按键类
class KeyPress {
function KeyDown(obj, KeyValue) {
local KeyEvent = obj.getVar(KeyValue.tostring()); //声明储存器
KeyEvent.clear_vector(); //清空储存器的向量位
if (sq_IsKeyDown(KeyValue, ENUM_SUBKEY_TYPE_ALL) && KeyEvent.getInt(0) == 0) {
KeyEvent.setInt(0, 1);
return true;
}
}
function KeyUp(obj, KeyValue) {
local KeyEvent = obj.getVar(KeyValue.tostring()); //声明储存器
if (sq_IsKeyUp(KeyValue, ENUM_SUBKEY_TYPE_ALL)) {
KeyEvent.setInt(0, 0);
}
}
function isKeyPress(KeyValue) {
local obj = sq_getMyCharacter();
if (KeyPress.KeyDown(obj, KeyValue)) {
return true;
}
KeyPress.KeyUp(obj, KeyValue);
}
}
//Key 键盘按键类
class KeyPressNB {
function KeyDown(obj, KeyValue, VarKey) {
local KeyEvent = obj.getVar(VarKey); //声明储存器
KeyEvent.clear_vector(); //清空储存器的向量位
if (sq_IsKeyDown(KeyValue, ENUM_SUBKEY_TYPE_ALL) && KeyEvent.getInt(0) == 0) {
KeyEvent.setInt(0, 1);
return true;
}
}
function KeyUp(obj, KeyValue, VarKey) {
local KeyEvent = obj.getVar(VarKey); //声明储存器
if (sq_IsKeyUp(KeyValue, ENUM_SUBKEY_TYPE_ALL)) {
KeyEvent.setInt(0, 0);
}
}
function isKeyPress(KeyValue, VarKey) {
local obj = sq_getMyCharacter();
obj = sq_GetCNRDObjectToActiveObject(obj);
if (KeyPressNB.KeyDown(obj, KeyValue, VarKey)) {
return true;
}
KeyPressNB.KeyUp(obj, KeyValue, VarKey);
}
}
//基础工具类
class Rindro_BaseToolClass {
function IsNumber(value) {
try {
local Buffer = value.tointeger();
return true;
} catch (exception) {
return false;
}
}
function GetItemNameById(ItemId) {
local ItemObject = L_sq_GetItem(ItemId);
local NamePointer = L_sq_RA(ItemObject + 0x20);
local ItemName = NativePointer(L_sq_I2P(NamePointer)).readUnicodeString();
return ItemName;
}
function SendPack(T) {
local str = Json.Encode(T);
L_sq_SendPackType(130);
L_sq_SendPackWChar(str);
L_sq_SendPack();
}
function SendPackEx(T) {
local str = L_sq_EncondeJson(T);
L_sq_SendPackType(130);
L_sq_SendPackWChar(str);
L_sq_SendPack();
}
function RegisterPack(Id, CallBack) {
Pack_Control.rawset(Id, CallBack);
}
function RegisterHexPack(Id, CallBack)
{
Pack_Hex_Control.rawset(Id, CallBack);
}
//绘制简易静态Ani // obj -- ani路径 -- X -- Y -- 第几帧 -- ani名字
function T_DrawStayAni(obj, aniFileName, x, y, index, aniname) {
local SelectAni = obj.getVar().GetAnimationMap(aniname, aniFileName);
//sq_AnimationProc(SelectAni);
sq_DrawSpecificFrame(SelectAni, x, y, false, index, false, 1.0);
return SelectAni;
}
//绘制简易静态Ani // obj -- ani路径 -- X -- Y -- 第几帧 -- ani名字
function T_DrawStayAniRate(obj, aniFileName, x, y, index, aniname, rate) {
local SelectAni = obj.getVar().GetAnimationMap(aniname, aniFileName);
SelectAni.setImageRateFromOriginal(rate, rate);
//sq_AnimationProc(SelectAni);
sq_DrawSpecificFrame(SelectAni, x, y, false, index, false, 1.0);
return SelectAni;
}
//绘制简易动态Ani // obj -- ani路径 -- X -- Y -- ani名字
function T_DrawDynamicAni(obj, aniFileName, x, y, aniname) {
local ani = obj.getVar().GetAnimationMap(aniname, aniFileName);
sq_AnimationProc(ani);
sq_drawCurrentFrame(ani, x, y, true);
return ani;
}
//超简易绘制动态Ani
function DrawAniEx(X, Y, AniPath, ...) {
local AniName = "简易播放Ani:" + AniPath;
if (vargc > 0) AniName = vargv[0];
local obj = sq_getMyCharacter();
local ani = obj.getVar().GetAnimationMap(AniName, AniPath);
sq_AnimationProc(ani);
sq_drawCurrentFrame(ani, X, Y, true);
return ani;
}
//初始化根表成员
function InitClass(Name) {
local RootTab = getroottable();
if (RootTab.rawin(Name) == true) {
RootTab.rawdelete(Name);
}
}
//获取交互Npc名称
function GetEachNpcId() {
local OneAddress = L_sq_RA(0x1ADE0E0);
if (OneAddress) {
local TowAddress = L_sq_RA(OneAddress + 8);
if (TowAddress) {
local Id = L_sq_RA(TowAddress + 0x210);
return Id;
}
}
return null;
}
function DrawTriptych(X, Y, Width, Img, StartIndex) {
//如果没有载入img就载入
if (!Rindro_Image_GlobalMap.rawin(Img)) {
Rindro_Image_GlobalMap[Img] <- Rindro_Image(Img);
}
Rindro_Image_GlobalMap[Img].DrawPng(StartIndex, X, Y);
//获取第一张图片的宽
local FirstW = Rindro_Image_GlobalMap[Img].GetPng(StartIndex).GetWidth();
//获取中间的图片宽
local MiddleW = Rindro_Image_GlobalMap[Img].GetPng(StartIndex + 1).GetWidth();
//获得最后一张图片的宽
local LastW = Rindro_Image_GlobalMap[Img].GetPng(StartIndex + 2).GetWidth();
//绘制中间
Rindro_Image_GlobalMap[Img].DrawExPng(StartIndex + 1, X + FirstW, Y, 0, sq_RGBA(255, 255, 255, 250), (Width - LastW - FirstW).tofloat() / MiddleW, 1.0);
//绘制最后一张
Rindro_Image_GlobalMap[Img].DrawPng(StartIndex + 2, X + Width - LastW, Y);
}
function DrawTriptychDetail(X, Y, Width, Img, Fi, Mi, La) {
//如果没有载入img就载入
if (!Rindro_Image_GlobalMap.rawin(Img)) {
Rindro_Image_GlobalMap[Img] <- Rindro_Image(Img);
}
Rindro_Image_GlobalMap[Img].DrawPng(Fi, X, Y);
//获取第一张图片的宽
local FirstW = Rindro_Image_GlobalMap[Img].GetPng(Fi).GetWidth();
//获取中间的图片宽
local MiddleW = Rindro_Image_GlobalMap[Img].GetPng(Mi).GetWidth();
//获得最后一张图片的宽
local LastW = Rindro_Image_GlobalMap[Img].GetPng(La).GetWidth();
//绘制中间
Rindro_Image_GlobalMap[Img].DrawExPng(Mi, X + FirstW, Y, 0, sq_RGBA(255, 255, 255, 250), (Width - LastW - FirstW).tofloat() / MiddleW, 1.0);
//绘制最后一张
Rindro_Image_GlobalMap[Img].DrawPng(La, X + Width - LastW, Y);
}
function DrawNineBox(X, Y, Width, Height, Img, StartIndex) {
//如果没有载入img就载入
if (!Rindro_Image_GlobalMap.rawin(Img)) {
Rindro_Image_GlobalMap[Img] <- Rindro_Image(Img);
}
//绘制左上角
Rindro_Image_GlobalMap[Img].DrawPng(StartIndex, X, Y);
//获取左上角的图片宽高
local LeftTopW = Rindro_Image_GlobalMap[Img].GetPng(StartIndex).GetWidth();
local LeftTopH = Rindro_Image_GlobalMap[Img].GetPng(StartIndex).GetHeight();
//绘制上边
//获取上边的宽
local TopW = Rindro_Image_GlobalMap[Img].GetPng(StartIndex + 1).GetWidth();
Rindro_Image_GlobalMap[Img].DrawExPng(StartIndex + 1, X + LeftTopW, Y, 0, sq_RGBA(255, 255, 255, 250), (Width - LeftTopW * 2).tofloat() / TopW, 1.0);
//绘制右上角
Rindro_Image_GlobalMap[Img].DrawPng(StartIndex + 2, X + Width - LeftTopW, Y);
//绘制左边
//获取左边的高
local LeftH = Rindro_Image_GlobalMap[Img].GetPng(StartIndex + 3).GetHeight();
Rindro_Image_GlobalMap[Img].DrawExPng(StartIndex + 3, X, Y + LeftTopH, 0, sq_RGBA(255, 255, 255, 250), 1.0, (Height - LeftTopH * 2).tofloat() / LeftH);
//绘制中间
//获取中间的宽高
local MiddleW = Rindro_Image_GlobalMap[Img].GetPng(StartIndex + 4).GetWidth();
local MiddleH = Rindro_Image_GlobalMap[Img].GetPng(StartIndex + 4).GetHeight();
Rindro_Image_GlobalMap[Img].DrawExPng(StartIndex + 4, X + LeftTopW, Y + LeftTopH, 0, sq_RGBA(255, 255, 255, 250), (Width - LeftTopW * 2).tofloat() / MiddleW, (Height - LeftTopH * 2).tofloat() / MiddleH);
//绘制右边
Rindro_Image_GlobalMap[Img].DrawExPng(StartIndex + 5, X + Width - LeftTopW, Y + LeftTopH, 0, sq_RGBA(255, 255, 255, 250), 1.0, (Height - LeftTopH * 2).tofloat() / LeftH);
//绘制左下角
Rindro_Image_GlobalMap[Img].DrawPng(StartIndex + 6, X, Y + Height - LeftTopH);
//绘制下边
Rindro_Image_GlobalMap[Img].DrawExPng(StartIndex + 7, X + LeftTopW, Y + Height - LeftTopH, 0, sq_RGBA(255, 255, 255, 250), (Width - LeftTopW * 2).tofloat() / TopW, 1.0);
//绘制右下角
Rindro_Image_GlobalMap[Img].DrawPng(StartIndex + 8, X + Width - LeftTopW, Y + Height - LeftTopH);
}
}
//获取文字绘制长度
class LenheartTextClass {
function GetStringLength(str) {
if (typeof str != "string") str = "无字符";
return L_sq_GetStringDrawLength(str);
}
}
class MemoryTool {
//给指定地址写入字节数组
function WirteByteArr(Address, ByteArr) {
for (local i = 0; i< ByteArr.len(); i++) {
L_sq_WAB(Address + i, ByteArr[i]);
}
}
//解密读取内存地址的数据
function DecodeMemoryData(Address) {
local nEax, nEcx8, nEsi, nEdx, nTmp;
nEax = NativePointer(L_sq_I2P(Address)).readInt();
if (nEax == -1) return nEax;
nEcx8 = NativePointer(L_sq_I2P(Address + 8)).readInt();
if (nEcx8 == -1) return nEcx8;
nEsi = NativePointer(L_sq_I2P(0x1AF8D78)).readInt();
if (nEsi == -1) return nEdx;
nEdx = nEax >> 16;
nTmp = (nEdx << 2) + nEsi + 36;
nEdx = NativePointer(L_sq_I2P(nTmp)).readInt();
if (nEdx == -1) return nEdx;
nEax = nEax & 65535;
nTmp = (nEax << 2) + nEdx + 8468;
nEax = NativePointer(L_sq_I2P(nTmp)).readInt();
if (nEax == -1) return nEax;
nEdx = nEax & 0xFFFF;
nEsi = nEdx << 16;
nEsi = nEsi | nEdx;
nEax = nEsi ^ nEcx8;
return nEax;
}
//加密写入内存地址数据
function EncodeMemoryData(AddreSs, Data) {
local JEdi, JEcx, JEax, JEsi, JEdx, JSs;
JEcx = AddreSs;
JEax = L_sq_RA(0x1AF8DB8);
JEax = JEax + 1;
L_sq_WA(0x1AF8DB8, JEax);
JEdx = JEax;
JEdx = JEdx >> 8;
JEdx = JEdx << 24;
JEdx = JEdx >> 24;
JEdx = L_sq_RA(JEdx * 2 + 0x1843F58);
JEdx = JEdx & 0xFFFF;
JEax = JEax << 24;
JEax = JEax >> 24;
JSs = L_sq_RA(JEax * 2 + 0x1844158);
JSs = JSs & 0xFFFF;
JEdx = JEdx ^ JSs;
JEax = JEdx;
JEax = JEax & 0xFFFF;
JEsi = Data;
JEdx = JEsi >> 16;
JSs = JEsi & 0xFFFF;
JEdx = JEdx + JSs;
JEdx = JEdx ^ JEax;
JEdi = JEdx;
JEdx = JEax;
JEax = JEax << 16;
JEax = JEax + JEdx;
JEsi = Data;
JEax = JEax ^ JEsi;
JEsi = AddreSs + 8;
L_sq_WA(JEsi, JEax);
JEax = L_sq_RA(AddreSs);
JEsi = L_sq_RA(0x1AF8D78);
JEcx = JEdi;
JEcx = JEcx << 16;
JEcx = JEcx + JEdx;
JEdx = JEax;
JEdx = JEdx >> 16;
JEdx = L_sq_RA(JEsi + JEdx * 4 + 36);
JEax = JEax & 0xFFFF;
L_sq_WA(JEdx + JEax * 4 + 8468, JEcx);
}
function DecodeMemoryDataF(Address) {
local Value = MemoryTool.DecodeMemoryData(Address);
local Bl = blob();
Bl.writen(Value, 'i');
Bl.seek(0);
return Bl.readn('f');
}
function ReadFloat(Address) {
local Arr = [];
for (local i = 0; i< 4; i++) {
Arr.append(L_sq_RAB(Address + i));
}
// local Value = L_sq_RAB(Address);
// print(Value);
local Bl = blob();
foreach(intvalue in Arr) {
Bl.writen(intvalue, 'c');
}
// Bl.writen(Value, 'i');
Bl.seek(0);
return Bl.readn('f');
}
}
//大数字
class longlong {
Value = null;
//构造函数 不管是不是string类型都要转成string类型
constructor(StrValue) {
Value = StrValue.tostring();
}
function _add(other) {
return longlong(L_sq_LongLongOperation(this.Value, other.Value, "+"));
}
function _sub(other) {
return longlong(L_sq_LongLongOperation(this.Value, other.Value, "-"));
}
function _mul(other) {
return longlong(L_sq_LongLongOperation(this.Value, other.Value, "*"));
}
function _div(other) {
return L_sq_LongLongOperation(this.Value, other.Value, "/");
}
function _unm() {
return longlong(L_sq_LongLongOperation(longlong("0"), this.Value, "-"));
}
function _modulo(other) {
return longlong(L_sq_LongLongOperation(this.Value, other.Value, "%"));
}
function GetFormat(FType) {
local Buf = L_sq_LongLongOperation(this.Value, FType, "format");
if (Buf.len()< 2) return Buf + ".0";
local Value = Buf.slice(0, -1);
local Unit = Buf.slice(-1);
local RetStr = format(FType + Unit, Value.tofloat());
return RetStr;
}
}
//任务队列
class QuestQueue {
//队列
Queue = null;
constructor() {
Queue = {};
}
//添加任务
function AddQuest(QuestName, QuestLogic, ...) {
local args = null;
if (vargc > 0) {
args = [];
for (local i = 0; i< vargc; i++) {
args.append(vargv[i]);
}
}
Queue[QuestName] <- {
Logic = QuestLogic,
InseartTime = Clock(),
arg = args
};
}
//移除任务
function RemoveQuest(QuestName) {
if (Queue) {
Queue.rawdelete(QuestName);
}
}
//执行任务
function Run() {
if (Queue) {
local NowTime = Clock();
foreach(QuestName, QuestInfo in Queue) {
if (QuestInfo.arg && QuestInfo.arg.len() > 0) {
local Arr = [];
Arr.append(getroottable());
Arr.append(QuestName);
Arr.append(NowTime);
foreach(value in QuestInfo.arg) {
Arr.append(value);
}
QuestInfo.Logic.acall(Arr);
// QuestInfo.Logic(QuestName, NowTime - QuestInfo.InseartTime, QuestInfo.arg);
} else QuestInfo.Logic(QuestName, NowTime - QuestInfo.InseartTime);
}
}
}
//示例
/*
Obj.AddQuest("测试任务",function (Name,Time)
{
print(Time);
if(Time >= 2000)Obj.RemoveQuest(Name);
}.bindenv(this));
*/
}

View File

@@ -0,0 +1,60 @@
/*
文件名:Hacker_Class.nut
路径:Base/_Tool/Hacker_Class.nut
创建日期:2024-09-24 06:25
文件用途:
*/
class _Rindro_Hacker {
HookTable = null;
constructor() {
HookTable = {};
}
function UnLoadHook(AddressStr) {
Sq_DeHookFunc(HookTable[AddressStr]);
}
function LoadHook(AddressStr, ArgumentArr, EnterFunc, LeaveFunc) {
//如果已经HOOK过 需要先卸载原来的HOOK
if (HookTable.rawin(AddressStr)) {
UnLoadHook(AddressStr);
print("地址: " + AddressStr + " 已经装载了Hook,本次操作将会卸载之前的Hook在执行。")
}
local Controler = Sq_HookFunc(AddressStr, ArgumentArr, EnterFunc, LeaveFunc);
HookTable.rawset(AddressStr, Controler);
}
}
//初始化Hacker
if (!(getroottable().rawin("Rindro_Haker"))) Rindro_Haker <- _Rindro_Hacker();
//重选角色时触发的回调函数(进入赛利亚房间)
OnSetCharacter_Control <- {}
Rindro_Haker.LoadHook(0x674350, ["pointer", "int"],
function(args) {
foreach(Func in OnSetCharacter_Control) {
Func();
}
return null;
},
function(args) {
return null;
});
OnSetCharacter_Control.MarrySystem <- function() {
if (getroottable().rawin("Yosin_14SkillXpos1") &&
getroottable().rawin("Yosin_14SkillXpos2") &&
getroottable().rawin("Yosin_14SkillYpos1") &&
getroottable().rawin("Yosin_14SkillYpos2")
) {
for (local i = 6; i< 7; i++) {
L_sq_WA(L_sq_RA(L_sq_RA(0x01ADE0CC) + 0x30 + (i * 0x4)) + 0x14, Yosin_14SkillXpos1 + (i * 31));
L_sq_WA(L_sq_RA(L_sq_RA(0x01ADE0CC) + 0x30 + (i * 0x4)) + 0x18, Yosin_14SkillYpos1);
L_sq_WA(L_sq_RA(L_sq_RA(0x01ADE0CC) + 0x60 + (i * 0x4)) + 0x14, Yosin_14SkillXpos2 + (i * 31));
L_sq_WA(L_sq_RA(L_sq_RA(0x01ADE0CC) + 0x60 + (i * 0x4)) + 0x18, Yosin_14SkillYpos2);
}
}
};

View File

@@ -0,0 +1,301 @@
/*
文件名:Hacker_RegApi.nut
路径:Base/_Tool/Hacker_RegApi.nut
创建日期:2024-09-25 18:31
文件用途:注册API
*/
//工具类
class R_Utils {
String = {
FindLastSubstring = function(str, substring) {
local strLen = str.len();
local subLen = substring.len();
local lastIndex = -1;
for (local i = 0; i <= strLen - subLen; i++) {
local found = true;
for (local j = 0; j< subLen; j++) {
if (str[i + j] != substring[j]) {
found = false;
break;
}
}
if (found) {
lastIndex = i;
}
}
return lastIndex;
}
}
//播放音效
function PlaySound(SoundName) {
L_Sq_CallFunc(0x75BD70, "void", FFI_MS_CDECL, ["pointer", "int", "int", "int"], Memory.allocUtf8String(SoundName).C_Object, -1, 0, 0);
}
//读取文件内容
function ReadScript(Path, Size, CodePage) {
local ReadPath = L_sq_P2I(Memory.allocUtf8String(Path).C_Object);
local Reader = Memory.alloc(Size);
local ReadBuffer = L_sq_P2I(Reader.C_Object);
L_Sq_CallFunc(0x11A2030, "int", FFI_FASTCALL, ["int", "int", "int", "int", "int", "int"], 0x1D17638, 0, ReadPath, ReadBuffer, 0x100000, 0x19DAF4);
if (CodePage == "utf8")
return Reader.readUtf8String();
if (CodePage == "unicode")
return Reader.readUnicodeString();
if (CodePage == "big5")
return Reader.readBig5String();
}
//读取文件
function GetScriptFileReader(Path, ...) {
local AllocSize = 102400;
if (vargc > 0) AllocSize = vargv[0];
//读取路径
local ReadPath = L_sq_P2I(Memory.allocUtf8String(Path).C_Object);
//读取缓存
local Reader = Memory.alloc(AllocSize);
local ReadBuffer = L_sq_P2I(Reader.C_Object);
//实际读取大小
local ReadSizeer = Memory.alloc(4);
local ReadSizeBuffer = L_sq_P2I(ReadSizeer.C_Object);
local Flag = L_Sq_CallFunc(0x59E3D0, "bool", FFI_MS_CDECL, ["int", "int", "int", "int"], ReadPath, ReadBuffer, AllocSize, ReadSizeBuffer);
if (Flag) {
return {
Buffer = Reader,
Size = ReadSizeer.readInt()
};
} else return null;
}
//读取配置表
function ReadScriptConfig(Path, Size, ...) {
local CodePage = "utf8";
if (vargc > 0) CodePage = vargv[0];
local Script = R_Utils.ReadScript(Path, Size, CodePage);
local Func = compilestring("return " + Script);
local Ret = Func();
return Ret;
}
//获取一个指定装备的角色对象
function GetCharacByEqu(Job, GrowType, Equ) {
local Obj = sq_CreateCharacter(Job, GrowType);
local ObjAddress = L_Sq_GetObjectAddress(Obj);
foreach(value in Equ) {
local ItemObject = L_sq_GetItem(value);
// L_Sq_CallFunc(0x825570, "void", FFI_THISCALL, ["int", "int"], ObjAddress, ItemObject);
L_Sq_CallFunc(0x8265A0, "void", FFI_THISCALL, ["int", "int", "int"], ObjAddress, ItemObject, -1);
}
return sq_GetCNRDObjectToSQRCharacter(Obj);
}
//获取装备编号的得文件路径
function GetEquPath(Equ) {
local EquPathAddress = L_Sq_CallFunc(0x1219E80, "int", FFI_THISCALL, ["int", "int"], 0x1d7993c, Equ);
if (EquPathAddress) {
return NativePointer(EquPathAddress).readUnicodeString();
}
return null;
}
//获取Lst文件的返回Array
function GetLstArr(Path, Header) {
local Arr = [];
local LstBuf = R_Utils.GetScriptFileReader(Path);
if (LstBuf) {
local IO = Sq_Point2Blob(L_sq_P2I(LstBuf.Buffer.C_Object), LstBuf.Size);
local i = 2;
while (i< LstBuf.Size) {
if ((LstBuf.Size - i) >= 10) {
IO.seek(i + 6); //内容指示位
local FindKey = IO.readn('i');
local Key = Rindro_Script.GetBinString(FindKey);
if (Key) {
local StrFilePath = Header + Key.tolower();
Arr.append(StrFilePath);
}
} else break;
i += 10;
}
}
return Arr;
}
//通过处理函数获取文件Table
function GetFileTableByHandle(Path, Func) {
local Data = {};
local FileData = R_Utils.GetScriptFileReader(Path);
if (FileData) {
if (FileData.Size >= 7) {
//创建Blob对象
local IO = Sq_Point2Blob(L_sq_P2I(FileData.Buffer.C_Object), FileData.Size);
//以5为单步从第二位开始遍历字节
local i = 2;
while (true) {
if (i< FileData.Size && FileData.Size - i >= 5) {
i = Func(Data, IO, i);
} else break;
}
}
}
return Data;
}
}
//根据List读取文件地址
// Rindro_Haker.LoadHook(0x1219E80, ["int", "int", "int"],
// function(args) {
// // print(format("%02x", args[0]));
// // print(args[2]);
// return null;
// },
// function(args) {
// // print(666);
// // print(format("%02x", args.pop()));
// // TTTAni <- args.pop();
// // local Path = NativePointer(L_sq_I2P(args.pop())).readUnicodeString();
// // if (Path != "character/swordman/weapon/katana/kat_lowkogaras.equ" && Path != "new_elvengard.twn") {
// // print(args[0]);
// // print(args[1]);
// // // print(format("%02x", args[1]));
// // print(Path);
// // }
// return null;
// });
//可能是构造装备以及构造其他东西
// Rindro_Haker.LoadHook(0x972220, ["int", "int", "int", "int"],
// function(args) {
// // print(format("%02x", args[0]));
// // local AniPath = NativePointer(L_sq_I2P(args[0])).readUnicodeString();
// if (args[0] == 10402) {
// print(args[0]);
// print(args[1]);
// print(args[2]);
// }
// // print(args[2]);
// return null;
// },
// function(args) {
// // print(666);
// // print(format("%02x", args.pop()));
// // TTTAni <- args.pop();
// return null;
// });
//绘制字符
getroottable().DrawCodeCallBackFunc <- {};
// Rindro_Haker.LoadHook(0x1206BD0, ["int", "int", "int", "pointer", "int", "void"],
// function(args) {
// // print("nut:" + format("%02x", args[3]));
// if (args[3]) {
// // for (local i = 0; i< 10000; i++) {
// local DrawCode = NativePointer((args[3])).readUnicodeString();
// if (DrawCode in DrawCodeCallBackFunc)
// DrawCodeCallBackFunc[DrawCode](args);
// // }
// }
// return null;
// },
// function(args) {
// // print(666);
// // print(format("%02x", args.pop()));
// // TTTAni <- args.pop();
// return null;
// });
//绘制城镇回调
getroottable().DrawTownCallBackFunc <- {};
Rindro_Haker.LoadHook(0x1108700, ["int", "void"],
function(args) {
// print("nut:" + format("%02x", args[3]));
// print(format("%02x", args[0]));
foreach(Func in DrawTownCallBackFunc) {
Func();
}
return null;
},
function(args) {
// print(666);
// print(format("%02x", args.pop()));
// TTTAni <- args.pop();
return null;
});
//顺图
function Rindro_Gm_MoveMap(obj) {
if (sq_IsKeyDown(OPTION_HOTKEY_PAUSE_IN_TOWER, ENUM_SUBKEY_TYPE_ALL) && RINDROLOCAL) {
if (KeyPress.isKeyPress(0)) L_sq_MoveMap(2);
if (KeyPress.isKeyPress(1)) L_sq_MoveMap(0);
if (KeyPress.isKeyPress(2)) L_sq_MoveMap(3);
if (KeyPress.isKeyPress(3)) L_sq_MoveMap(1);
}
}
getroottable()["LenheartFuncTab"].rawset("Rindro_Gm_MoveMapFuncN", Rindro_Gm_MoveMap);
//丢弃物品回调
getroottable().DiscardItemCallBackFunc <- {};
function Sq_DiscardItem(Item) {
local Flag = true;
foreach(Func in DiscardItemCallBackFunc) {
local Ret = Func(Item);
if (!Ret) Flag = false;
}
return Flag;
}
//从exe获取字符串
getroottable()["Sq_GetExeStr_Map"] <- {};
function Sq_GetExeStr_Event(Index)
{
if(Index in getroottable()["Sq_GetExeStr_Map"]){
return getroottable()["Sq_GetExeStr_Map"][Index](Index);
}
return Index;
}
// //hook打开窗口
// Rindro_Haker.LoadHook(0xE6E070, ["int","int","int","int","void"],
// function(args) {
// return null;
// },
// function(args) {
// // print(666);
// // print(format("%02x", args.pop()));
// // TTTAni <- args.pop();
// return null;
// });
// Rindro_Haker.LoadHook(0xE6E070, ["int", "int", "int", "int", "int"],
// function(args) {
// print("nut:" + format("%02x", args[0]));
// print("nut:" + format("%02x", args[1]));
// print("nut:" + format("%02x", args[2]));
// print("nut:" + format("%02x", args[3]));
// return null;
// },
// function(args) {
// // print(666);
// // print(format("%02x", args.pop()));
// // TTTAni <- args.pop();
// return null;
// });

View File

@@ -0,0 +1,80 @@
/*
文件名:Image_Class.nut
路径:Base/_Tool/Image_Class.nut
创建日期:2024-10-21 16:58
文件用途: 图片类
*/
class Rindro_Png {
C_Object = null;
Path = null;
Idx = null;
constructor(Object, Path, Idx) {
this.Path = Path;
this.Idx = Idx;
this.C_Object = Object;
}
function Draw(X, Y) {
L_Sq_CallFunc(0x11A8F60, "int", FFI_THISCALL, ["int", "int", "int", "int"], NativePointer(0x1B45B94).readInt(), X, Y, this.C_Object);
}
function DrawEx(X, Y, Model, Rgba, Xrate, Yrate) {
L_Sq_CallFunc(0x11A97E0, "int", FFI_THISCALL, ["int", "int", "int", "int", "float", "float", "float", "int", "float", "float"], NativePointer(0x1B45B94).readInt(), X, Y, this.C_Object, Xrate, Yrate, Model, Rgba, 0, 0);
}
function GetWidth()
{
return NativePointer(this.C_Object + 0x1C).readShort();
}
function GetHeight()
{
return NativePointer(this.C_Object + 0x1E).readShort();
}
}
class Rindro_Image {
Img = null;
Path = null;
constructor(Path) {
this.Path = Path;
//读取Img
Img = L_Sq_CallFunc(0x11C0410, "int", FFI_THISCALL, ["int", "int", "int"], NativePointer(0x1B4684C).readInt(), 0, L_sq_P2I(Memory.allocUtf8String(Path).C_Object));
}
function GetPng(Idx) {
if (Img) {
local PngObject = L_Sq_CallFunc(0x11AA190, "int", FFI_THISCALL, ["int", "int"], Img, Idx);
return Rindro_Png(PngObject, Path, Idx);
}
}
function DrawPng(Idx, X, Y) {
local Buffer = GetPng(Idx);
Buffer.Draw(X, Y);
}
function DrawExPng(Idx, X, Y, Model, Rgba, Xrate, Yrate) {
local Buffer = GetPng(Idx);
Buffer.DrawEx(X, Y, Model, Rgba, Xrate, Yrate)
}
//加载
function Load(Path) {
if (!(getroottable().rawin("Rindro_Image_Map"))) getroottable().Rindro_Image_Map <- {};
if (getroottable().Rindro_Image_Map.rawin(Path)) return getroottable().Rindro_Image_Map[Path];
else {
getroottable().Rindro_Image_Map[Path] <- Rindro_Image(Path);
return getroottable().Rindro_Image_Map[Path];
}
}
}
Rindro_Image_GlobalMap <- {};
Rindro_Image_GlobalMap["lenheartui"] <- Rindro_Image("interface/lenheartwindowcommon.img");
/*
local Png = TestImg.GetPng(0);
Png.Draw(200, 200);
Png.DrawEx(100, 400, 0, sq_RGBA(255, 255, 255, 255), 1.5, 1.5);
*/

661
CSBase/_Tool/Json_Class.nut Normal file
View File

@@ -0,0 +1,661 @@
/*
文件名:Json_Class.nut
路径:Base/_Tool/Json_Class.nut
创建日期:2024-09-27 23:54
文件用途:Json类
*/
class JSONParser {
static version = "1.0.1";
state = "";
stack = null;
container = null;
key = "";
value = "";
converter = null;
constructor() {
stack = [];
container = {};
}
function parse(str, ...) {
if (vargc > 0) converter = vargc[0];
local string = {
go = function() {
state = "ok";
}.bindenv(this),
firstokey = function() {
key = value;
state = "colon";
}.bindenv(this),
okey = function() {
key = value;
state = "colon";
}.bindenv(this),
ovalue = function() {
value = this._convert(value, "string", converter);
state = "ocomma";
}.bindenv(this),
firstavalue = function() {
value = this._convert(value, "string", converter);
state = "acomma";
}.bindenv(this),
avalue = function() {
value = value;
this._convert(value, "string", converter);
state = "acomma";
}.bindenv(this)
};
local number = {
go = function() {
state = "ok";
}.bindenv(this),
ovalue = function() {
value = this._convert(value, "number", converter);
state = "ocomma";
}.bindenv(this),
firstavalue = function() {
value = this._convert(value, "number", converter);
state = "acomma";
}.bindenv(this),
avalue = function() {
value = this._convert(value, "number", converter);
state = "acomma";
}.bindenv(this)
};
local action = {};
action["{"] <- {
go = function() {
stack.push({
state = "ok"
});
container = {};
state = "firstokey";
}.bindenv(this),
ovalue = function() {
stack.push({
container = container,
state = "ocomma",
key = key
});
container = {};
state = "firstokey";
}.bindenv(this),
firstavalue = function() {
stack.push({
container = container,
state = "acomma"
});
container = {};
state = "firstokey";
}.bindenv(this),
avalue = function() {
stack.push({
container = container,
state = "acomma"
});
container = {};
state = "firstokey";
}.bindenv(this)
},
action["}"] <- {
firstokey = function() {
local pop = stack.pop();
value = container;
container = ("container" in pop) ? pop.container : null;
key = ("key" in pop) ? pop.key : null;
state = pop.state;
}.bindenv(this),
ocomma = function() {
local pop = stack.pop();
container[key] <- value;
value = container;
container = ("container" in pop) ? pop.container : null;
key = ("key" in pop) ? pop.key : null;
state = pop.state;
}.bindenv(this)
},
action["["] <- {
go = function() {
stack.push({
state = "ok"
});
container = [];
state = "firstavalue";
}.bindenv(this),
ovalue = function() {
stack.push({
container = container,
state = "ocomma",
key = key
});
container = [];
state = "firstavalue";
}.bindenv(this),
firstavalue = function() {
stack.push({
container = container,
state = "acomma"
});
container = [];
state = "firstavalue";
}.bindenv(this),
avalue = function() {
stack.push({
container = container,
state = "acomma"
});
container = [];
state = "firstavalue";
}.bindenv(this)
},
action["]"] <- {
firstavalue = function() {
local pop = stack.pop();
value = container;
container = ("container" in pop) ? pop.container : null;
key = ("key" in pop) ? pop.key : null;
state = pop.state;
}.bindenv(this),
acomma = function() {
local pop = stack.pop();
container.push(value);
value = container;
container = ("container" in pop) ? pop.container : null;
key = ("key" in pop) ? pop.key : null;
state = pop.state;
}.bindenv(this)
},
action[":"] <- {
colon = function() {
local err = false;
foreach(akey, avalue in container) {
if (akey == key) err = true;
break
}
if (err) throw "Duplicate key \"" + key + "\"";
state = "ovalue";
}.bindenv(this)
},
action[","] <- {
ocomma = function() {
container[key] <- value;
state = "okey";
}.bindenv(this),
acomma = function() {
container.push(value);
state = "avalue";
}.bindenv(this)
},
action["true"] <- {
go = function() {
value = true;
state = "ok";
}.bindenv(this),
ovalue = function() {
value = true;
state = "ocomma";
}.bindenv(this),
firstavalue = function() {
value = true;
state = "acomma";
}.bindenv(this),
avalue = function() {
value = true;
state = "acomma";
}.bindenv(this)
},
action["false"] <- {
go = function() {
value = false;
state = "ok";
}.bindenv(this),
ovalue = function() {
value = false;
state = "ocomma";
}.bindenv(this),
firstavalue = function() {
value = false;
state = "acomma";
}.bindenv(this),
avalue = function() {
value = false;
state = "acomma";
}.bindenv(this)
},
action["null"] <- {
go = function() {
value = null;
state = "ok";
}.bindenv(this),
ovalue = function() {
value = null;
state = "ocomma";
}.bindenv(this),
firstavalue = function() {
value = null;
state = "acomma";
}.bindenv(this),
avalue = function() {
value = null;
state = "acomma";
}.bindenv(this)
}
state = "go";
stack = [];
local start = 0;
try {
local result, token, tokenizer = _JSONTokenizer();
while (token = tokenizer.nextToken(str, start)) {
if ("ptfn" == token.type) {
action[token.value][state]();
} else if ("number" == token.type) {
value = token.value;
number[state]();
} else if ("string" == token.type) {
value = tokenizer.unescape(token.value);
string[state]();
}
start += token.length;
}
} catch (e) {
state = e;
}
if (state != "ok" || regexp("[^\\s]").capture(str, start)) {
local near = str.slice(start, GetMin(str.len(), start + 10));
throw "JSON Syntax Error near `" + near + "`";
}
return value;
}
function GetMin(a, b) {
return a< b ? a : b;
}
function _convert(value, type, converter) {
if ("function" == typeof converter) {
local parametercCount = 2;
if ("getinfos" in converter) {
parametercCount = converter.getinfos().parameters.len() -
1;
}
if (parametercCount == 1) {
return converter(value);
} else if (parametercCount == 2) {
return converter(value, type);
} else {
throw "Error: converter function must take 1 or 2 parameters"
}
} else if ("number" == type) {
local Ret = (value.find(".") == null && value.find("e") == null && value.find("E") == null) ? value.tointeger() : value.tofloat();
return Ret;
} else {
return value;
}
}
}
class _JSONTokenizer {
_ptfnRegex = null;
_numberRegex = null;
_stringRegex = null;
_ltrimRegex = null;
_unescapeRegex = null;
constructor() {
this._ptfnRegex = regexp("^(?:\\,|\\:|\\[|\\]|\\{|\\}|true|false|null)");
this._numberRegex = regexp("^(?:\\-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)");
this._stringRegex = regexp("^(?:\\\"((?:[^\\r\\n\\t\\\\\\\"]|\\\\(?:[\"\\\\\\/trnfb]|u[0-9a-fA-F]{4}))*)\\\")");
this._ltrimRegex = regexp("^[\\s\\t\\n\\r]*");
this._unescapeRegex = regexp("\\\\(?:(?:u\\d{4})|[\\\"\\\\/bfnrt])");
}
function nextToken(str, ...) {
local start = 0;
if (vargc > 0) start = vargv[0];
local
m,
type,
token,
value,
length,
whitespaces;
whitespaces = this._leadingWhitespaces(str, start);
start += whitespaces;
if (m = this._ptfnRegex.capture(str, start)) {
value = str.slice(m[0].begin, m[0].end);
type = "ptfn";
} else if (m = this._numberRegex.capture(str, start)) {
value = str.slice(m[0].begin, m[0].end);
type = "number";
} else if (m = this._stringRegex.capture(str, start)) {
value = str.slice(m[1].begin, m[1].end);
type = "string";
} else {
return null;
}
token = {
type = type,
value = value,
length = m[0].end - m[0].begin + whitespaces
};
return token;
}
function _leadingWhitespaces(str, start) {
local r = this._ltrimRegex.capture(str, start);
if (r) {
return r[0].end - r[0].begin;
} else {
return 0;
}
}
_unescapeReplacements = {
b = "\b",
f = "\f",
n = "\n",
r = "\r",
t = "\t"
};
function unescape(str) {
local start = 0;
local res = "";
while (start< str.len()) {
local m = this._unescapeRegex.capture(str, start);
if (m) {
local token = str.slice(m[0].begin, m[0].end);
local pre = str.slice(start, m[0].begin);
res += pre;
if (token.len() == 6) {
res += token;
} else {
local char = token.slice(1);
if (char in this._unescapeReplacements) {
res += this._unescapeReplacements[char];
} else {
res += char;
}
}
} else {
res += str.slice(start);
break;
}
start = m[0].end;
}
return res;
}
}
class JSONEncoder {
static VERSION = "2.0.0";
static _maxDepth = 32;
function encode(value) {
return this._encode(value);
}
function _encode(val, ...) {
local depth = 0;
if (vargc > 0) depth = vargv[0];
if (depth > this._maxDepth) {
throw "Possible cyclic reference";
}
local
r = "",
s = "",
i = 0;
switch (typeof val) {
case "table":
case "class":
s = "";
foreach(k, v in val) {
if (typeof v != "function") {
s += ",\"" + k + "\":" + this._encode(v, depth + 1);
}
}
s = s.len() > 0 ? s.slice(1) : s;
r += "{" + s + "}";
break;
case "array":
s = "";
for (i = 0; i< val.len(); i++) {
s += "," + this._encode(val[i], depth + 1);
}
s = (i > 0) ? s.slice(1) : s;
r += "[" + s + "]";
break;
case "integer":
case "float":
case "bool":
r += val;
break;
case "null":
r += "null";
break;
case "instance":
if ("_serializeRaw" in val && typeof val._serializeRaw == "function") {
r += val._serializeRaw().tostring();
} else if ("_serialize" in val && typeof val._serialize == "function") {
r += this._encode(val._serialize(), depth + 1);
} else {
s = "";
try {
foreach(k, v in val) {
s += ",\"" + k + "\":" + this._encode(v, depth + 1);
}
} catch (e) {
foreach(k, v in val.getclass()) {
if (typeof v != "function") {
s += ",\"" + k + "\":" + this._encode(val[k], depth + 1);
}
}
}
s = s.len() > 0 ? s.slice(1) : s;
r += "{" + s + "}";
}
break;
case "blob":
r += "\"" + (val.len() ? this._escape(val.tostring()) : "") + "\"";
break;
default:
r += "\"" + this._escape(val.tostring()) + "\"";
break;
}
return r;
}
function _escape(str) {
local res = "";
for (local i = 0; i< str.len(); i++) {
local ch1 = (str[i] & 0xFF);
if ((ch1 & 0x80) == 0x00) {
ch1 = format("%c", ch1);
if (ch1 == "\"") {
res += "\\\"";
} else if (ch1 == "\\") {
res += "\\\\";
} else if (ch1 == "/") {
res += "\\/";
} else if (ch1 == "\b") {
res += "\\b";
} else if (ch1 == "\f") {
res += "\\f";
} else if (ch1 == "\n") {
res += "\\n";
} else if (ch1 == "\r") {
res += "\\r";
} else if (ch1 == "\t") {
res += "\\t";
} else if (ch1 == "\0") {
res += "\\u0000";
} else {
res += ch1;
}
} else {
if ((ch1 & 0xE0) == 0xC0) {
local ch2 = (str[++i] & 0xFF);
res += format("%c%c", ch1, ch2);
} else if ((ch1 & 0xF0) == 0xE0) {
local ch2 = (str[++i] & 0xFF);
local ch3 = (str[++i] & 0xFF);
res += format("%c%c%c", ch1, ch2, ch3);
} else if ((ch1 & 0xF8) == 0xF0) {
local ch2 = (str[++i] & 0xFF);
local ch3 = (str[++i] & 0xFF);
local ch4 = (str[++i] & 0xFF);
res += format("%c%c%c%c", ch1, ch2, ch3, ch4);
}
}
}
return res;
}
}

View File

@@ -0,0 +1,204 @@
/*
文件名:MemoryClass.nut
路径:Base/_Tool/MemoryClass.nut
创建日期:2024-09-24 08:22
文件用途:
*/
class Memory {
function alloc(Size) {
return NativePointer(Size.tostring());
}
function allocUtf8String(Str) {
return NativePointer(Str_Ptr(Str));
}
}
class NativePointer {
//大小
Size = -1;
C_Object = null;
constructor(T) {
if (type(T) == "integer") {
C_Object = L_sq_I2P(T);
} else if (type(T) == "userdata") {
C_Object = T;
} else if (type(T) == "string") {
C_Object = Sq_New_Point(T.tointeger());
Size = T;
//注册销毁伪析构
Register_Destruction(C_Object, this);
}
}
function add(intoffset) {
return NativePointer(L_sq_I2P(L_sq_P2I(this.C_Object) + intoffset));
}
function sub(intoffset) {
return NativePointer(L_sq_I2P(L_sq_P2I(this.C_Object) - intoffset));
}
function writeByteArray(arr) {
Sq_Memory_WriteByteArr(this.C_Object, arr);
}
function readByteArray(size) {
local PointB = Sq_Point2Blob(this.C_Object, size);
local arr = [];
foreach(value in PointB) {
arr.append(value);
}
return arr;
}
function write(value, type) {
local Buf = blob(0);
Buf.writen(value, type);
local arr = [];
foreach(value in Buf) {
arr.append(value);
}
writeByteArray(arr);
}
function writeS8(value) {
write(value, 'c');
}
function writeU8(value) {
write(value, 'b');
}
function writeS16(value) {
write(value, 's');
}
function writeU16(value) {
write(value, 'w');
}
function writeS32(value) {
write(value, 'i');
}
function writeU32(value) {
write(value, 'i');
}
function writeShort(value) {
write(value, 's');
}
function writeUShort(value) {
write(value, 'w');
}
function writeInt(value) {
write(value, 'i');
}
function writeUInt(value) {
write(value, 'i');
}
function writeFloat(value) {
write(value, 'f');
}
function writeDouble(value) {
write(value, 'd');
}
function read(type) {
local Buf = Sq_Point2Blob(L_sq_P2I(this.C_Object), 4);
return Buf.readn(type);
}
function readS8() {
return read('c');
}
function readU8() {
return read('b');
}
function readS16() {
return read('s');
}
function readU16() {
return read('w');
}
function readS32() {
return read('i');
}
function readU32() {
return read('i');
}
function readShort() {
return read('s');
}
function readUShort() {
return read('w');
}
function readInt() {
return read('i');
}
function readUInt() {
return read('i');
}
function readFloat() {
return read('f');
}
function readDouble() {
return read('d');
}
function readUnicodeString(...) {
if (vargc > 0) {
return Sq_Memory_ReadString(this.C_Object, vargv[0]);
} else {
return Sq_Memory_ReadString(this.C_Object);
}
}
function readUtf8String(...) {
if (vargc > 0) {
return Sq_Memory_ReadStringByUtf8(this.C_Object, vargv[0]);
} else {
return Sq_Memory_ReadStringByUtf8(this.C_Object);
}
}
function readBig5String(...) {
if (vargc > 0) {
return Sq_Memory_ReadStringByBig5(this.C_Object, vargv[0]);
} else {
return Sq_Memory_ReadStringByBig5(this.C_Object);
}
}
function readPointer() {
return Sq_ReadPoint(this.C_Object);
}
function tostring() {
return this.C_Object.tostring();
}
}

View File

@@ -0,0 +1,61 @@
/*
文件名:Pack_Class.nut
路径:Base/_Tool/Pack_Class.nut
创建日期:2025-06-30 09:24
文件用途:字节包
*/
class Packet {
//读取指针位置
Index = 0;
//内存数据
Pointer = null;
//包大小
Size = 0;
//加载包
function Load(P, S) {
Pointer = P;
Size = S;
}
//读取指针跳转
function Seek(...) {
local Pos = vargv[0];
local Mode = 0;
if(vargc > 1) Mode = vargv[1];
if (Mode == 0) {
Index = Pos;
} else if (Mode == 1) {
Index += Pos;
} else if (Mode == 2) {
Index -= Pos;
}
}
//读取整形
function GetInt() {
local Size_t = 4;
if (Index + Size_t > Size) {
print("读取包越界!");
return;
}
local Buf = NativePointer(Pointer).add(Index).readInt();
Index += Size_t;
return Buf;
}
//读取流
function GetStream(Size_t) {
if (Index + Size_t > Size) {
print("读取包越界!");
return;
}
local Np = NativePointer(Pointer).add(Index);
Np.Size = Size_t;
Index += Size_t;
return Np;
}
}

View File

@@ -0,0 +1,713 @@
/*
文件名: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 charPtrToInt(arr) {
local value = ((arr[0]) << 0) |
((arr[1]) << 8) |
((arr[2]) << 16) |
((arr[3]) << 24);
return value;
}
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 _PVF_Data_ {
//数据
Data = null;
//位置
Pos = 0;
//最大值
Max = 0;
function _typeof() {
return "pvf_data";
}
constructor(gData) {
Data = gData;
Max = gData.len();
}
function Last() {
if (Pos > 0) {
Pos--;
return Get();
}
return null;
}
function Seek(i) {
if (Pos > 0 && Pos<(Max - 1)) {
Pos = i;
}
}
function Get() {
local Ret = Data[Pos];
if (Pos<(Max - 1)) {
Pos++;
}
return Ret;
}
function Eof() {
if (Pos == Max - 1)
return true;
}
function Next() {
if (Pos<(Max - 1)) {
Pos++;
return Get();
}
return null;
}
}
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);
} else {
Rindro_Script_Bin_Data.append("");
}
CurrentIndex++;
}
}
}
function GetBinString(Index) {
if (!(getroottable().rawin("ENUM_TW_GROWTYPE_VERS")) || ENUM_TW_GROWTYPE_VERS >= 24112901) //24112901更新了新的读取bin文件的方式
return L_sq_StringBinById(Index);
else {
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.GetInt();
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: {
IO.seek(-4, 'c');
local ret = IO.readn('i');
return ret;
}
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 IOBUF = Sq_Point2Blob(L_sq_P2I(ReadObject.Buffer.C_Object), ReadObject.Size);
local IO = BlobEx(IOBUF.readblob(IOBUF.len()));
//以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);
i += 5;
for (local z = 0; z< Count; z++) {
local Layer = Rindro_Script.UnpackData(IO, i);
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;
}
//隐藏图层
else if (str == "[hide layer]") {
EquipmentAtt["hidelayer"] <- [];
while (true) {
local Buffer = Rindro_Script.UnpackData(IO, i);
i += 5;
if (Buffer == "[/hide layer]") {
break;
}
EquipmentAtt["hidelayer"].append(Buffer);
}
}
//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);
i += 5;
local Index2 = Rindro_Script.UnpackData(IO, i);
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);
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;
}
//获取文件并处理
function GetFileData(Path, Func) {
local N_Buffer = R_Utils.GetScriptFileReader(Path);
if (N_Buffer) {
local IO = Sq_Point2Blob(L_sq_P2I(N_Buffer.Buffer.C_Object), N_Buffer.Size);
IO = BlobEx(IO.readblob(IO.len()));
return Rindro_Script.ResolvingData(IO, Func, Path);
} else {
print(Path + "找不到文件!");
return null;
}
}
function ResolvingData(IO, Func, Path) {
local DataTable = {};
DataTable.filepath <- Path;
local DataArr = [];
local Length = IO.len();
if (Length >= 7) {
local i = 2;
while (true) {
if (i< Length && Length - i >= 5) {
local str = Rindro_Script.UnpackData(IO, i);
i += 5;
DataArr.push(str);
} else break;
}
Func(DataTable, _PVF_Data_(DataArr));
return DataTable;
}
return null;
}
}
// Rindro_Script.GetBin();
Rindro_Script.InitLoad_String();