359 lines
12 KiB
Plaintext
359 lines
12 KiB
Plaintext
|
|
/*
|
|||
|
|
文件名:Exchange.nut
|
|||
|
|
路径:Project/Exchange/Exchange.nut
|
|||
|
|
创建日期:2025-07-23 00:02
|
|||
|
|
文件用途:交易所
|
|||
|
|
*/
|
|||
|
|
class ExchangeC extends LenheartNewUI_Windows {
|
|||
|
|
//包头
|
|||
|
|
Op = 21001000;
|
|||
|
|
|
|||
|
|
//调试模式
|
|||
|
|
// DeBugMode = true;
|
|||
|
|
|
|||
|
|
//不是窗口
|
|||
|
|
// NoWindow = true;
|
|||
|
|
|
|||
|
|
//是否可见
|
|||
|
|
Visible = false;
|
|||
|
|
|
|||
|
|
//手续费
|
|||
|
|
Commission = 0;
|
|||
|
|
|
|||
|
|
//最低价Map
|
|||
|
|
MinPriceMap = null;
|
|||
|
|
|
|||
|
|
//待回收道具
|
|||
|
|
RecoveryItem = null;
|
|||
|
|
//绘制对象的信息
|
|||
|
|
DrawItemCurObject = null;
|
|||
|
|
|
|||
|
|
//输入框
|
|||
|
|
InputObject = null;
|
|||
|
|
//上架价值
|
|||
|
|
InputValue = null;
|
|||
|
|
|
|||
|
|
|
|||
|
|
//时间对象
|
|||
|
|
Timer = null;
|
|||
|
|
|
|||
|
|
Img = Rindro_Image("interface2/yosin/exchange.img");
|
|||
|
|
LenheartUI = Rindro_Image("interface/lenheartwindowcommon.img");
|
|||
|
|
|
|||
|
|
//遍历背包查找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),
|
|||
|
|
name = NativePointer(L_sq_I2P(L_sq_RA(FindAddress + 0x20))).readUnicodeString(),
|
|||
|
|
level = L_sq_RA(FindAddress + 0x8)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH) {
|
|||
|
|
Childrens = [];
|
|||
|
|
Timer = Clock();
|
|||
|
|
|
|||
|
|
//注册控件
|
|||
|
|
RegisterWidget();
|
|||
|
|
|
|||
|
|
LenheartNewUI_Windows.constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH);
|
|||
|
|
|
|||
|
|
|
|||
|
|
//初始化PVF配置
|
|||
|
|
InitScriptConfig();
|
|||
|
|
|
|||
|
|
|
|||
|
|
DiscardItemCallBackFunc.rawset("ExchangeC", DiscardItem.bindenv(this));
|
|||
|
|
|
|||
|
|
|
|||
|
|
DiscardItem(1011932160);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
function InitScriptConfig() {
|
|||
|
|
MinPriceMap = {};
|
|||
|
|
Rindro_Script.GetFileData("etc/rindro/exchange/exchange.etc", function(DataTable, Data) {
|
|||
|
|
while (!Data.Eof()) {
|
|||
|
|
local Str = Data.Get();
|
|||
|
|
if (Str == "[commission]") {
|
|||
|
|
Commission = Data.Get().tofloat() * 0.01;
|
|||
|
|
} else if (Str == "[bottom price]") {
|
|||
|
|
while (!Data.Eof()) {
|
|||
|
|
local Str = Data.Get();
|
|||
|
|
local Str2 = Data.Get();
|
|||
|
|
if (Str == "[/bottom price]") break;
|
|||
|
|
else {
|
|||
|
|
MinPriceMap[Str] <- Str2.tointeger();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}.bindenv(this));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//回收道具回调
|
|||
|
|
function DiscardItem(ItemAddress) {
|
|||
|
|
// print(ItemAddress);
|
|||
|
|
if (!Visible) return true;
|
|||
|
|
else {
|
|||
|
|
local info = FindItemPosByForeachInven(ItemAddress);
|
|||
|
|
if (info) {
|
|||
|
|
RecoveryItem = null;
|
|||
|
|
DrawItemCurObject = null;
|
|||
|
|
InputObject.str = "";
|
|||
|
|
InputValue = null;
|
|||
|
|
|
|||
|
|
info.ObjectAddress <- ItemAddress;
|
|||
|
|
RecoveryItem = info;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function RegisterNpc(id) {
|
|||
|
|
local EachManager = getroottable()["L_Each_Obj"];
|
|||
|
|
//先清空注册
|
|||
|
|
EachManager.RemoveEachForNpc(id);
|
|||
|
|
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.OnClick = function(Button) {
|
|||
|
|
//打开背包
|
|||
|
|
L_sq_Open_ExWindow(0x1ADE090, 0, 0, 1);
|
|||
|
|
Button.Parent.CloseAllEach();
|
|||
|
|
Button.Parent.CloseWindow();
|
|||
|
|
Visible = true;
|
|||
|
|
ResetFocus();
|
|||
|
|
}.bindenv(this);
|
|||
|
|
ApplyEngagementButton.SetCallBackFunc(function(Button) {})
|
|||
|
|
SThis.AddChild(ApplyEngagementButton);
|
|||
|
|
}.bindenv(this));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function RegisterWidget() {
|
|||
|
|
//关闭按钮
|
|||
|
|
local CloseButton = LenheartNewUI_BaseButton(332, 0, 11, 12, "interface/lenheartwindowcommon.img", 276);
|
|||
|
|
CloseButton.OnClick = function() {
|
|||
|
|
this.Visible = false;
|
|||
|
|
}.bindenv(this);
|
|||
|
|
AddChild(CloseButton);
|
|||
|
|
|
|||
|
|
local CloseButton = LenheartNewUI_ButtonText(80, 324, 5, "上架");
|
|||
|
|
CloseButton.SetTextOffset(0, 1);
|
|||
|
|
CloseButton.OnClick = function() {
|
|||
|
|
if (!RecoveryItem) return;
|
|||
|
|
local equvalue = InputValue.tointeger();
|
|||
|
|
//如果是装备判断一下最低价格
|
|||
|
|
if (RecoveryItem.type == 0) {
|
|||
|
|
local EquipLevel = RecoveryItem.level;
|
|||
|
|
local MinPrice = getMinPrice(EquipLevel);
|
|||
|
|
if (equvalue< MinPrice) {
|
|||
|
|
equvalue = MinPrice;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
local T = {
|
|||
|
|
op = Op + 1,
|
|||
|
|
type = RecoveryItem.type,
|
|||
|
|
pos = RecoveryItem.pos,
|
|||
|
|
value = equvalue
|
|||
|
|
}
|
|||
|
|
SendPackEx(T);
|
|||
|
|
RecoveryItem = null;
|
|||
|
|
DrawItemCurObject = null;
|
|||
|
|
InputObject.str = "";
|
|||
|
|
InputValue = null;
|
|||
|
|
}.bindenv(this);
|
|||
|
|
AddChild(CloseButton);
|
|||
|
|
|
|||
|
|
local CloseButton = LenheartNewUI_ButtonText(210, 324, 5, "取消");
|
|||
|
|
CloseButton.SetTextOffset(0, 1);
|
|||
|
|
CloseButton.OnClick = function() {
|
|||
|
|
this.Visible = false;
|
|||
|
|
RecoveryItem = null;
|
|||
|
|
DrawItemCurObject = null;
|
|||
|
|
InputObject.str = "";
|
|||
|
|
InputValue = null;
|
|||
|
|
}.bindenv(this);
|
|||
|
|
AddChild(CloseButton);
|
|||
|
|
|
|||
|
|
//输入框
|
|||
|
|
InputObject = LenheartNewUI_BaseInput(120, 209, 110, 20);
|
|||
|
|
InputObject.CallBack = function(Input, oldStr) {
|
|||
|
|
if (Rindro_BaseToolClass.IsNumber(Input.str)) {
|
|||
|
|
local buf = Input.str.tointeger();
|
|||
|
|
if (buf == 2147483647) {
|
|||
|
|
Input.SetStr("2147483647");
|
|||
|
|
}
|
|||
|
|
InputValue = buf;
|
|||
|
|
}
|
|||
|
|
}.bindenv(this);
|
|||
|
|
AddChild(InputObject);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
function getMinPrice(equiplevel) {
|
|||
|
|
// 从当前等级开始查找
|
|||
|
|
local currentLevel = equiplevel;
|
|||
|
|
|
|||
|
|
// 循环查找更低的等级,直到找到或等级小于1
|
|||
|
|
while (currentLevel >= 1) {
|
|||
|
|
// 检查当前等级是否存在于映射表中
|
|||
|
|
if (MinPriceMap.rawin(currentLevel)) {
|
|||
|
|
return MinPriceMap[currentLevel];
|
|||
|
|
}
|
|||
|
|
// 降低一个等级继续查找
|
|||
|
|
currentLevel--;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 如果所有等级都找不到,返回null或默认值
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//绘制主界面
|
|||
|
|
function DrawMain(obj) {
|
|||
|
|
|
|||
|
|
Rindro_BaseToolClass.DrawNineBox(X - 2, Y + 14, 354, 350, "interface/lenheartwindowcommon.img", 0); //背景框
|
|||
|
|
//绘制背景图
|
|||
|
|
Img.DrawPng(0, X + 0, Y + 0);
|
|||
|
|
//绘制点卷图标
|
|||
|
|
Img.DrawPng(1, X + 100, Y + 210);
|
|||
|
|
|
|||
|
|
//绘制标题
|
|||
|
|
L_sq_DrawCode("上架物品", X + 152, Y + 3, sq_RGBA(221, 197, 147, 250), 1, 1);
|
|||
|
|
|
|||
|
|
//如果有上架道具 则绘制
|
|||
|
|
if (RecoveryItem) {
|
|||
|
|
DrawItemCur(RecoveryItem.ObjectAddress, RecoveryItem, X + 162, Y + 80);
|
|||
|
|
L_sq_DrawCode(RecoveryItem.name, X + 176 - LenheartTextClass.GetStringLength(RecoveryItem.name) / 2, Y + 130, sq_RGBA(221, 197, 147, 250), 1, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (InputValue) {
|
|||
|
|
local CommissionStr = (InputValue * Commission).tointeger().tostring(); //手续费
|
|||
|
|
local EstimatedRevenue = (InputValue - (InputValue * Commission)).tointeger().tostring();
|
|||
|
|
L_sq_DrawCode("手续费: " + CommissionStr, X + 154 - (LenheartTextClass.GetStringLength(CommissionStr) / 2), Y + 247, sq_RGBA(221, 197, 147, 250), 1, 1);
|
|||
|
|
L_sq_DrawCode("预计收入: " + EstimatedRevenue, X + 146 - (LenheartTextClass.GetStringLength(EstimatedRevenue) / 2), Y + 282, sq_RGBA(221, 197, 147, 250), 1, 1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
//绘制项目
|
|||
|
|
function DrawItemCur(Object, Info, XPos, Ypos) {
|
|||
|
|
local Id = L_sq_RA(Object + 0x1C);
|
|||
|
|
local Rarity = L_sq_RA(Object + 0xF4);
|
|||
|
|
L_Sq_DrawItem(XPos, Ypos, Id, Info.count, 0, 0, 0);
|
|||
|
|
if (sq_IsIntersectRect(IMouse.GetXPos(), IMouse.GetYPos(), 1, 1, XPos, Ypos, 24, 24)) {
|
|||
|
|
//打开道具信息窗口
|
|||
|
|
if (!Info.vis) {
|
|||
|
|
//手动解锁道具信息窗口
|
|||
|
|
Sq_Memory_WriteByteArr(L_sq_I2P(0xF63DDA), [0x56, 0xE8, 0x10, 0xFE, 0xFF, 0xFF]);
|
|||
|
|
local ItemDrawInfo = L_Sq_CallFunc(0xE6E070, "int", FFI_THISCALL, ["int", "int", "int", "int"], L_sq_RA(0x1A5FB20), 275, Object, 41);
|
|||
|
|
//校准道具信息窗口位置
|
|||
|
|
L_Sq_CallFunc(0xF3B3B0, "int", FFI_THISCALL, ["int", "int", "int", "int", "int"], ItemDrawInfo, IMouse.GetXPos(), IMouse.GetYPos(), 24, 24);
|
|||
|
|
Info.vis = true;
|
|||
|
|
//我自己UI打开的道具信息窗口需要把渲染队列改为下层 以显示我打开的道具
|
|||
|
|
getroottable().WindowsShowABFlag <- false;
|
|||
|
|
DrawItemCurObject = Object;
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
if (Info.vis) {
|
|||
|
|
//关闭道具信息窗口
|
|||
|
|
L_Sq_CallFunc(0xE6B2B0, "int", FFI_THISCALL, ["int", "int", "int", "char"], 0x1ADE090, 0x113, 0xFFFFFFFF, 0x0);
|
|||
|
|
Info.vis = false;
|
|||
|
|
DrawItemCurObject = null;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Show(obj) {
|
|||
|
|
DrawMain(obj);
|
|||
|
|
LenheartNewUI_Windows.Show(obj);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//逻辑入口
|
|||
|
|
function Proc(obj) {
|
|||
|
|
//同步位移窗口逻辑
|
|||
|
|
local Window = sq_GetPopupWindowMainCotrol(64);
|
|||
|
|
if (Window) {
|
|||
|
|
X = Window.GetXPos() - 430;
|
|||
|
|
Y = Window.GetYPos() + 60;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//悬停已回收锁定逻辑
|
|||
|
|
local SelectItem = L_sq_RA(0x1AE45B4);
|
|||
|
|
if (RecoveryItem && RecoveryItem.rawin("ObjectAddress")) {
|
|||
|
|
if (RecoveryItem.ObjectAddress == SelectItem) {
|
|||
|
|
R_Mouse.Lock();
|
|||
|
|
_Rindro_Cusor_.ForceLockState = true;
|
|||
|
|
} else {
|
|||
|
|
_Rindro_Cusor_.ForceLockState = false;
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
_Rindro_Cusor_.ForceLockState = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
LenheartNewUI_Windows.SyncPos(X, Y);
|
|||
|
|
|
|||
|
|
if (Timer) {
|
|||
|
|
if (Clock() - Timer >= 2000) {
|
|||
|
|
Timer = null;
|
|||
|
|
RegisterNpc(1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//override
|
|||
|
|
//鼠标右键按下回调
|
|||
|
|
function OnMouseRbDown(MousePos_X, MousePos_Y) {
|
|||
|
|
if (DrawItemCurObject && RecoveryItem) {
|
|||
|
|
local Info = RecoveryItem;
|
|||
|
|
if (Info.vis) {
|
|||
|
|
//关闭道具信息窗口
|
|||
|
|
L_Sq_CallFunc(0xE6B2B0, "int", FFI_THISCALL, ["int", "int", "int", "char"], 0x1ADE090, 0x113, 0xFFFFFFFF, 0x0);
|
|||
|
|
Info.vis = false;
|
|||
|
|
RecoveryItem = null;
|
|||
|
|
DrawItemCurObject = null;
|
|||
|
|
InputObject.str = "";
|
|||
|
|
InputValue = null;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//调用原生方法
|
|||
|
|
LenheartNewUI_Windows.OnMouseLbDown(MousePos_X, MousePos_Y);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
function Lenheart_Exchange_Fun(obj) {
|
|||
|
|
local RootTab = getroottable();
|
|||
|
|
if (!RootTab.rawin("Exchange_Obj")) {
|
|||
|
|
RootTab.rawset("Exchange_Obj", true);
|
|||
|
|
LenheartNewUI_CreateWindow(ExchangeC, "交易所窗口", 43, 128, 420, 412, 0);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
getroottable()["LenheartFuncTab"].rawset("ExchangeFuncN", Lenheart_Exchange_Fun);
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
// L_Windows_List <- [];
|
|||
|
|
// getroottable().rawdelete("LenheartPluginsInitFlag");
|
|||
|
|
// getroottable().rawdelete("EventList_Obj")
|
|||
|
|
// getroottable().rawdelete("Exchange_Obj");
|