2025-11-04 20:17:53 +08:00
|
|
|
/*
|
|
|
|
|
文件名:NpcTransaction.nut
|
|
|
|
|
路径:Project/NpcTransaction/NpcTransaction.nut
|
|
|
|
|
创建日期:2025-10-23 12:50
|
|
|
|
|
文件用途:NPC交易系统
|
|
|
|
|
*/
|
|
|
|
|
class NpcTransactionC extends LenheartNewUI_Windows {
|
|
|
|
|
//调试模式
|
|
|
|
|
// DeBugMode = true;
|
|
|
|
|
|
|
|
|
|
//不是窗口
|
|
|
|
|
// NoWindow = true;
|
|
|
|
|
|
|
|
|
|
//是否可见
|
2025-11-08 12:21:06 +08:00
|
|
|
Visible = false;
|
2025-11-04 20:17:53 +08:00
|
|
|
|
2025-11-08 12:21:06 +08:00
|
|
|
NPCPath = null;
|
2025-11-04 20:17:53 +08:00
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
|
2025-11-08 12:21:06 +08:00
|
|
|
NPCAvatar = null;
|
|
|
|
|
//当前交易NPC头像信息
|
|
|
|
|
CurNpcAvatar = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-11-04 20:17:53 +08:00
|
|
|
constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH) {
|
|
|
|
|
Childrens = [];
|
2025-11-08 12:21:06 +08:00
|
|
|
NPCAvatar = {};
|
2025-11-04 20:17:53 +08:00
|
|
|
//注册控件
|
|
|
|
|
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;
|
2025-11-25 12:53:39 +08:00
|
|
|
R_Utils.PlaySound("GOLD_PAY_OUT");
|
2025-11-04 20:17:53 +08:00
|
|
|
}
|
2025-11-08 12:21:06 +08:00
|
|
|
if (Jso.rawin("equ")) {
|
2025-11-04 20:17:53 +08:00
|
|
|
TransactionEqu = Jso.equ;
|
2025-11-25 12:53:39 +08:00
|
|
|
} else {
|
|
|
|
|
R_Utils.PlaySound("ALERT_2");
|
2025-11-04 20:17:53 +08:00
|
|
|
}
|
|
|
|
|
}.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) {
|
2025-11-08 12:21:06 +08:00
|
|
|
if (mode >= 1 && mode< 3) {
|
2025-11-04 20:17:53 +08:00
|
|
|
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);
|
|
|
|
|
|
2025-11-08 12:21:06 +08:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-04 20:17:53 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
//置换装备
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//交易装备
|
2025-11-08 12:21:06 +08:00
|
|
|
if (TransactionEqu) {
|
2025-11-04 20:17:53 +08:00
|
|
|
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);
|
|
|
|
|
}
|
2025-11-25 12:53:39 +08:00
|
|
|
R_Utils.PlaySound("CHANGE_ALERT");
|
2025-11-04 20:17:53 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//遍历背包查找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);
|
|
|
|
|
}
|
2025-11-08 12:21:06 +08:00
|
|
|
} else if (Fragment == "[value]") {
|
2025-11-04 20:17:53 +08:00
|
|
|
while (true) {
|
|
|
|
|
local Fbuf = Data.Get();
|
|
|
|
|
if (Fbuf == "[/value]") {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
local Value = Data.Get();
|
|
|
|
|
EquList.rawset(Fbuf, Value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
2025-11-08 12:21:06 +08:00
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
});
|
2025-11-04 20:17:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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();
|
2025-11-25 12:53:39 +08:00
|
|
|
R_Utils.PlaySound("WINDOW_SHOW");
|
2025-11-04 20:17:53 +08:00
|
|
|
}.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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-08 12:21:06 +08:00
|
|
|
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];
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-04 20:17:53 +08:00
|
|
|
function InitWindow() {
|
2025-11-08 12:21:06 +08:00
|
|
|
CurNpcAvatar = GetNpcAvatar(CurNpcId);
|
2025-11-04 20:17:53 +08:00
|
|
|
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);
|