Rindro-Sqr/Project/NpcTransaction/NpcTransaction.nut

381 lines
12 KiB
Plaintext

/*
文件名:NpcTransaction.nut
路径:Project/NpcTransaction/NpcTransaction.nut
创建日期:2025-10-23 12:50
文件用途:NPC交易系统
*/
class NpcTransactionC extends LenheartNewUI_Windows {
//调试模式
// DeBugMode = true;
//不是窗口
// NoWindow = true;
//是否可见
Visible = false;
NPCPath = null;
EquList = null;
NPCList = null;
Dialog = null;
CurDialog = -1;
mode = 0;
DiaTimer = 0;
//置换装备
ReplacementEqu = null;
//交易金币
TransactionGlod = 0;
//交易装备
TransactionEqu = null;
Img = Rindro_Image("npctransation/main.img");
Charc = null;
PlayerName = "无名";
PlayerLevel = 0;
AvatarInfoIdx = [0x3038, 0x3010, 0x3014, 0x3018, 0x301c, 0x3020, 0x3024, 0x3028, 0x302c, 0x3030, 0x3034];
NpcName = "赛利亚";
//当前交互NPCId
CurNpcId = -1;
NPCAvatar = null;
//当前交易NPC头像信息
CurNpcAvatar = null;
constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH) {
Childrens = [];
NPCAvatar = {};
//注册控件
RegisterWidget();
LenheartNewUI_Windows.constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH);
InifPvf();
RegNpc();
local obj = sq_getMyCharacter();
local C_Object = L_sq_RA(0x1ab7cdc);
local job = sq_getJob(obj);
//记录装备
local equiitemsbuf = [];
foreach(offset in AvatarInfoIdx) {
local AvatarEquiAddress = L_sq_RA(C_Object + offset);
if (AvatarEquiAddress >= 0x400000) {
local NormalIndex = L_sq_RA(AvatarEquiAddress + 0x1c);
local ExIndex = L_sq_RA(AvatarEquiAddress + 0x13E0);
equiitemsbuf.append(ExIndex == 0 ? NormalIndex : ExIndex);
}
}
Charc = Rindro_Draw_Character(job, equiitemsbuf, "rest.ani", null);
PlayerName = L_Sq_GetObjectName(obj);
PlayerLevel = L_Sq_GetObjectLevel(obj);
DiscardItemCallBackFunc.rawset("RecoveryC", DiscardItem.bindenv(this));
Pack_Control.rawset(21005002, function(Chunk) {
local Jso = Json.Decode(Chunk);
local flag = Jso.flag;
CurDialog = flag;
mode = flag;
DiaTimer = Clock();
if (Jso.rawin("glod")) {
TransactionGlod = Jso.glod;
R_Utils.PlaySound("GOLD_PAY_OUT");
}
if (Jso.rawin("equ")) {
TransactionEqu = Jso.equ;
} else {
R_Utils.PlaySound("ALERT_2");
}
}.bindenv(this));
Pack_Control.rawset(21005006, function(Chunk) {
ReplacementEqu = null;
}.bindenv(this));
}
function RegisterWidget() {
//关闭按钮
local CloseButton = LenheartNewUI_BaseButton(250, 14, 11, 12, "interface/lenheartwindowcommon.img", 276);
CloseButton.OnClick = function() {
this.Visible = false;
}.bindenv(this);
Childrens.append(CloseButton);
//确认按钮
local ConfirmButton = LenheartNewUI_ButtonText(56, 313, 15, "同意交易");
ConfirmButton.DWidth = 18;
ConfirmButton.Width = 74;
ConfirmButton.SetTextOffset(-4, 1);
ConfirmButton.OnClickEx = function(Btn) {
if (!Btn.Visible) return;
local T = {
op = 21005003,
npc = CurNpcId,
}
SendPackEx(T);
CloseWindow();
}.bindenv(this);
ConfirmButton.SetCallBackFunc(function(Btn) {
if (mode >= 1 && mode< 3) {
Btn.Visible = true;
} else {
Btn.Visible = false;
}
}.bindenv(this));
AddChild(ConfirmButton);
local CancelButton = LenheartNewUI_ButtonText(145, 313, 15, "取消交易");
CancelButton.DWidth = 18;
CancelButton.Width = 74;
CancelButton.SetTextOffset(-4, 1);
CancelButton.OnClick = function() {
CloseWindow();
}.bindenv(this);
AddChild(CancelButton);
}
//绘制主界面
function DrawMain(obj) {
Img.DrawPng(0, X, Y);
if (Charc) Charc.DrawFace(X + 20, Y + 188);
L_sq_DrawCode("Lv." + PlayerLevel.tostring(), X + 46, Y + 185, sq_RGBA(179, 169, 135, 255), 0, 1);
L_sq_DrawCode(PlayerName, X + 46, Y + 196, sq_RGBA(179, 169, 135, 255), 0, 1);
if (CurNpcAvatar) {
L_sq_DrawImg(CurNpcAvatar.Path, CurNpcAvatar.Index, X + 20, Y + 44);
L_sq_DrawCode(CurNpcAvatar.Name, X + 46, Y + 47, sq_RGBA(179, 169, 135, 255), 0, 1);
}
//置换装备
if (ReplacementEqu) {
L_Sq_DrawItem(X + 122, Y + 242, ReplacementEqu, 1, 0, 0, 0);
}
//交易金币
if (TransactionGlod > 0) {
L_sq_DrawCode(TransactionGlod.tostring(), X + 165, Y + 48, sq_RGBA(179, 169, 135, 255), 0, 1);
}
//交易装备
if (TransactionEqu) {
DrawItemBase(X + 122, Y + 98, TransactionEqu, 1);
}
//对话
if (Dialog && CurDialog != -1) {
ShowMessageBox(X + Dialog[CurDialog].x, Y + Dialog[CurDialog].y, Dialog[CurDialog].str);
}
}
function Show(obj) {
DrawMain(obj);
LenheartNewUI_Windows.Show(obj);
}
//逻辑入口
function Proc(obj) {
LenheartNewUI_Windows.SyncPos(X, Y);
if (DiaTimer != 0 && Clock() - DiaTimer > 2000) {
DiaTimer = 0;
CurDialog = -1;
}
}
//回收道具回调
function DiscardItem(ItemAddress) {
if (!Visible) return true;
else {
local info = FindItemPosByForeachInven(ItemAddress);
if (!EquList.rawin(info.itemId)) {
return;
}
if (info) {
info.op <- 21005001;
info.npc <- CurNpcId;
ReplacementEqu = info.itemId;
SendPackEx(info);
}
R_Utils.PlaySound("CHANGE_ALERT");
}
}
//遍历背包查找Item
function FindItemPosByForeachInven(FindAddress) {
local Inven = L_sq_RA(0x1A5FB24);
local InvenAdd = L_sq_RA(Inven + 56);
InvenAdd += 36;
for (local z = 0; z< 5; z++) {
for (local i = 0; i< 48; i++) {
local ItemAdd = L_sq_RA(InvenAdd + ((i + (z * 48)) * 4));
if (ItemAdd == FindAddress) return {
type = z,
pos = i,
vis = false,
count = MemoryTool.DecodeMemoryData(FindAddress + 0x1A4),
itemId = L_sq_RA(FindAddress + 0x1c)
}
}
}
return null;
}
function InifPvf() {
EquList = {};
Rindro_Script.GetFileData("etc/rindro/npctransaction/npctransaction.etc", function(DataTable, Data) {
while (!Data.Eof()) {
local Fragment = Data.Get();
if (Fragment == "[npc list]") {
NPCList = [];
while (true) {
local Fbuf = Data.Get();
if (Fbuf == "[/npc list]") {
break;
}
NPCList.append(Fbuf);
}
} else if (Fragment == "[event dialog]") {
Dialog = [];
for (local i = 0; i< 4; i++) {
local T = {
str = Sq_ConvertWideChar(Data.Get(), "big5"),
x = Data.Get(),
y = Data.Get()
}
Dialog.append(T);
}
} else if (Fragment == "[value]") {
while (true) {
local Fbuf = Data.Get();
if (Fbuf == "[/value]") {
break;
}
local Value = Data.Get();
EquList.rawset(Fbuf, Value);
}
}
}
});
NPCPath = {};
Rindro_Script.GetFileData("npc/npc.lst", function(DataTable, Data) {
while (!Data.Eof()) {
local Id = Data.Get();
local Path = "npc/" + Data.Get().tolower();
NPCPath.rawset(Id, Path);
}
});
}
function RegNpc() {
local EachManager = getroottable()["L_Each_Obj"];
foreach(id in NPCList) {
EachManager.AddEachForNpc(id, function(SThis) {
//关闭按钮
local ApplyEngagementButton = LenheartNewUI_Each_BaseButton(0, 0, 100, 21, "interface2/popup_menu/popup_back.img", 3);
ApplyEngagementButton.Icon = "interface2/popup_menu/popup_icon_cn.img";
ApplyEngagementButton.IconIdx = 27;
ApplyEngagementButton.Str = "交易";
ApplyEngagementButton.Data = SThis.NPC_Index;
ApplyEngagementButton.OnClick = function(Button) {
CurNpcId = Button.Data;
TransactionEqu = null;
TransactionGlod = 0;
mode = 0;
ReplacementEqu = null;
CurDialog = -1;
InitWindow();
//打开背包
L_sq_Open_ExWindow(0x1ADE090, 0, 0, 1);
Button.Parent.CloseAllEach();
Button.Parent.CloseWindow();
ResetFocus();
R_Utils.PlaySound("WINDOW_SHOW");
}.bindenv(this);
ApplyEngagementButton.SetCallBackFunc(function(Button) {})
SThis.AddChild(ApplyEngagementButton);
}.bindenv(this));
}
}
function ShowMessageBox(X, Y, STR) {
local StrDrawLen = LenheartTextClass.GetStringLength(STR);
local WLen = ((StrDrawLen - 30) / 12) + 1;
local HLen = (StrDrawLen / 110);
WLen = WLen > 7 ? 7 : WLen;
//Item信息框一般为211的宽度
L_sq_DrawImg("interface/messageballoon.img", 49, X + (-50 + (WLen * 12)), Y + 11 + ((HLen + 1) * 13));
L_sq_DrawWindow(X, Y, 30 + (WLen * 12), 21 + (HLen * 13), "interface/messageballoon.img", 40, 9, 12, 9, 13);
//绘制字符串
local Buf = L_sq_GetStringDrawArray(STR, 123);
foreach(Line, Str in Buf) {
L_sq_DrawCode(Str, X + 8, Y + 8 + (Line * 14), sq_RGBA(255, 255, 255, 255), 0, 1);
}
}
function GetNpcAvatar(Id) {
if (NPCAvatar.rawin(Id)) return NPCAvatar[Id];
//获取NPC路径
local Path = NPCPath.rawget(CurNpcId);
local Info = Rindro_Script.GetFileData(Path, function(DataTable, Data) {
while (!Data.Eof()) {
local Fragment = Data.Get();
if (Fragment == "[popup face]") {
DataTable.ImgPath <- Data.Get().tolower();
DataTable.Index <- Data.Get();
} else if (Fragment == "[name]") {
DataTable.Name <- Sq_ConvertWideChar(Data.Get(), "big5");
}
}
});
NPCAvatar.rawset(Id, {
Path = Info.ImgPath,
Index = Info.Index,
Name = Info.Name
});
return NPCAvatar[Id];
}
function InitWindow() {
CurNpcAvatar = GetNpcAvatar(CurNpcId);
Visible = true;
}
}
L_Windows_List <- [];
getroottable().rawdelete("LenheartPluginsInitFlag");
getroottable().rawdelete("EventList_Obj")
getroottable().rawdelete("NpcTransaction_Obj");
getroottable().rawdelete("L_Each_Obj");
function Lenheart_NpcTransaction_Fun(obj) {
local RootTab = getroottable();
if (!RootTab.rawin("NpcTransaction_Obj")) {
RootTab.rawset("NpcTransaction_Obj", true);
LenheartNewUI_CreateWindow(NpcTransactionC, "npc交易窗口", 100, 120, 272, 334, 32);
}
}
getroottable()["LenheartFuncTab"].rawset("NpcTransactionFuncN", Lenheart_NpcTransaction_Fun);