231 lines
8.6 KiB
Plaintext
231 lines
8.6 KiB
Plaintext
|
|
/*
|
|||
|
|
文件名:NpcTransaction.nut
|
|||
|
|
路径:Dps_A/ProjectClass/NpcTransaction/NpcTransaction.nut
|
|||
|
|
创建日期:2025-10-23 14:37
|
|||
|
|
文件用途:
|
|||
|
|
*/
|
|||
|
|
return;
|
|||
|
|
class NpcTransaction {
|
|||
|
|
|
|||
|
|
//装备价值
|
|||
|
|
EquValue = null;
|
|||
|
|
//品级装备组
|
|||
|
|
EquGroup = null;
|
|||
|
|
//金币易物浮动比例
|
|||
|
|
GoldFloat = 0.5;
|
|||
|
|
//最低交换品级
|
|||
|
|
MinRarity = 0;
|
|||
|
|
//交易消耗物品
|
|||
|
|
TradeItem = null;
|
|||
|
|
|
|||
|
|
//装备易物浮动等级
|
|||
|
|
EquFloatMin = 5;
|
|||
|
|
EquFloatMax = 5;
|
|||
|
|
|
|||
|
|
//事件概率
|
|||
|
|
EventRate = null;
|
|||
|
|
|
|||
|
|
//用户状态表
|
|||
|
|
UserState = null;
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
constructor() {
|
|||
|
|
//注册客户端收包
|
|||
|
|
RegisterClient();
|
|||
|
|
EquValue = {};
|
|||
|
|
UserState = {};
|
|||
|
|
EquGroup = [{}, {}, {}, {}, {}, {}, {}, {}];
|
|||
|
|
|
|||
|
|
//读取PVF
|
|||
|
|
InitPvf();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
function RegisterClient() {
|
|||
|
|
|
|||
|
|
ClientSocketPackFuncMap.rawset(21005001, function(SUser, Jso) {
|
|||
|
|
local lastTime = GetTransactionInfo(SUser, Jso);
|
|||
|
|
if (lastTime && Sq_GetTimestampString().slice(-9).tointeger() - lastTime.time< 3600000) {
|
|||
|
|
local T = {
|
|||
|
|
op = 21005002,
|
|||
|
|
flag = 3
|
|||
|
|
}
|
|||
|
|
SUser.SendJso(T);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
local InvenObj = SUser.GetInven();
|
|||
|
|
local Equ = InvenObj.GetSlot(Inven.INVENTORY_TYPE_ITEM, 9 + Jso.pos);
|
|||
|
|
if (Equ) {
|
|||
|
|
local EquId = Equ.GetIndex();
|
|||
|
|
if (EquId) {
|
|||
|
|
local equ = PvfItem.GetPvfItemById(EquId);
|
|||
|
|
local Rarity = equ.GetRarity();
|
|||
|
|
local Level = equ.GetUsableLevel();
|
|||
|
|
//判断是否解封装
|
|||
|
|
local CanTrade = GetTrade(InvenObj, Jso.pos);
|
|||
|
|
if ((Rarity == 2 || Rarity == 3) && CanTrade == 1) {
|
|||
|
|
local T = {
|
|||
|
|
op = 21005006,
|
|||
|
|
}
|
|||
|
|
SUser.SendJso(T);
|
|||
|
|
SUser.SendNotiPacketMessage("该装备属于封装装备,并已解封,无法进行交易!", 0);
|
|||
|
|
} else {
|
|||
|
|
//判断是进行什么交易逻辑
|
|||
|
|
local Random = MathClass.Rand(600, 1000);
|
|||
|
|
//嘲讽
|
|||
|
|
if (Random <= EventRate[0]) {
|
|||
|
|
local T = {
|
|||
|
|
op = 21005002,
|
|||
|
|
flag = 0
|
|||
|
|
}
|
|||
|
|
SUser.SendJso(T);
|
|||
|
|
|
|||
|
|
local Cid = SUser.GetCID();
|
|||
|
|
if (!UserState.rawin(Cid)) UserState[Cid] <- {};
|
|||
|
|
UserState[Cid].rawset(Jso.npc, {
|
|||
|
|
time = Sq_GetTimestampString().slice(-9).tointeger()
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
//金币易物
|
|||
|
|
else if (Random <= EventRate[1]) {
|
|||
|
|
local thGoldFloat = MathClass.Rand(-EquValue[EquId].tofloat() * GoldFloat, EquValue[EquId].tofloat() * GoldFloat);
|
|||
|
|
local Glod = EquValue[EquId].tofloat() + thGoldFloat;
|
|||
|
|
local T = {
|
|||
|
|
op = 21005002,
|
|||
|
|
flag = 1,
|
|||
|
|
glod = Glod
|
|||
|
|
}
|
|||
|
|
SUser.SendJso(T);
|
|||
|
|
|
|||
|
|
local Cid = SUser.GetCID();
|
|||
|
|
if (!UserState.rawin(Cid)) UserState[Cid] <- {};
|
|||
|
|
UserState[Cid].rawset(Jso.npc, {
|
|||
|
|
glod = Glod,
|
|||
|
|
pos = Jso.pos,
|
|||
|
|
oldid = EquId
|
|||
|
|
time = Sq_GetTimestampString().slice(-9).tointeger()
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
//装备易物
|
|||
|
|
else if (Random <= EventRate[2]) {
|
|||
|
|
local setarr = [];
|
|||
|
|
local findtable = EquGroup[Rarity];
|
|||
|
|
foreach(index, level in findtable) {
|
|||
|
|
if (level >= Level - EquFloatMin && level <= Level + EquFloatMax) {
|
|||
|
|
setarr.append(index);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
local SendId = setarr[MathClass.Rand(0, setarr.len() - 1)];
|
|||
|
|
local T = {
|
|||
|
|
op = 21005002,
|
|||
|
|
flag = 2,
|
|||
|
|
equ = SendId
|
|||
|
|
}
|
|||
|
|
SUser.SendJso(T);
|
|||
|
|
|
|||
|
|
local Cid = SUser.GetCID();
|
|||
|
|
if (!UserState.rawin(Cid)) UserState[Cid] <- {};
|
|||
|
|
UserState[Cid].rawset(Jso.npc, {
|
|||
|
|
equ = SendId,
|
|||
|
|
pos = Jso.pos,
|
|||
|
|
oldid = EquId
|
|||
|
|
time = Sq_GetTimestampString().slice(-9).tointeger()
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}.bindenv(this));
|
|||
|
|
|
|||
|
|
|
|||
|
|
ClientSocketPackFuncMap.rawset(21005003, function(SUser, Jso) {
|
|||
|
|
//获取交易结构体
|
|||
|
|
local Info = GetTransactionInfo(SUser, Jso);
|
|||
|
|
if (!Info) return;
|
|||
|
|
//获取旧装备ID
|
|||
|
|
local oldid = Info.oldid;
|
|||
|
|
//获取旧装备格子
|
|||
|
|
local pos = Info.pos;
|
|||
|
|
//检测扣除
|
|||
|
|
local InvenObj = SUser.GetInven();
|
|||
|
|
local Equ = InvenObj.GetSlot(Inven.INVENTORY_TYPE_ITEM, 9 + Info.pos);
|
|||
|
|
if (Equ.GetIndex() != oldid) {
|
|||
|
|
SUser.SendNotiBox("交易时请不要移动背包中装备的位置!", 1);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
Equ.Delete();
|
|||
|
|
|
|||
|
|
if (Info.rawin("equ")) {
|
|||
|
|
SUser.GiveItem(Info.equ, 1);
|
|||
|
|
SUser.SendNotiBox("与NPC交易获得装备 [" + PvfItem.GetNameById(Info.equ) + "]", 1);
|
|||
|
|
} else if (Info.rawin("glod")) {
|
|||
|
|
SUser.RechargeMoney(Info.glod);
|
|||
|
|
SUser.SendNotiBox("与NPC交易获得金币: " + Info.glod, 1);
|
|||
|
|
}
|
|||
|
|
SUser.SendItemSpace(0);
|
|||
|
|
}.bindenv(this));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function GetTransactionInfo(SUser, Jso) {
|
|||
|
|
try {
|
|||
|
|
local Info = UserState[SUser.GetCID()][Jso.npc];
|
|||
|
|
return Info;
|
|||
|
|
} catch (exception) {}
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function InitPvf() {
|
|||
|
|
Script();
|
|||
|
|
ScriptData.GetFileData("etc/rindro/npctransaction/npctransaction.etc", function(DataTable, Data) {
|
|||
|
|
while (!Data.Eof()) {
|
|||
|
|
local Fragment = Data.Get();
|
|||
|
|
if (Fragment == "[value]") {
|
|||
|
|
while (true) {
|
|||
|
|
local Fbuf = Data.Get();
|
|||
|
|
if (Fbuf == "[/value]") {
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
local Value = Data.Get();
|
|||
|
|
EquValue.rawset(Fbuf, Value);
|
|||
|
|
//读取装备品级
|
|||
|
|
local equ = PvfItem.GetPvfItemById(Fbuf);
|
|||
|
|
local Rarity = equ.GetRarity();
|
|||
|
|
local Level = equ.GetUsableLevel();
|
|||
|
|
EquGroup[Rarity].rawset(Fbuf, Level);
|
|||
|
|
}
|
|||
|
|
} else if (Fragment == "[random]") {
|
|||
|
|
GoldFloat = Data.Get().tofloat() / 100.0;
|
|||
|
|
} else if (Fragment == "[allow rarity]") {
|
|||
|
|
MinRarity = Data.Get();
|
|||
|
|
} else if (Fragment == "[exchange cost item]") {
|
|||
|
|
TradeItem = {
|
|||
|
|
item = Data.Get(),
|
|||
|
|
count = Data.Get()
|
|||
|
|
}
|
|||
|
|
} else if (Fragment == "[equipment random level lower]") {
|
|||
|
|
EquFloatMin = Data.Get();
|
|||
|
|
} else if (Fragment == "[equipment random level upper]") {
|
|||
|
|
EquFloatMax = Data.Get();
|
|||
|
|
} else if (Fragment == "[event rate]") {
|
|||
|
|
local o1 = Data.Get();
|
|||
|
|
local o2 = Data.Get();
|
|||
|
|
local o3 = Data.Get();
|
|||
|
|
|
|||
|
|
EventRate = [o1, o1 + o2, o1 + o2 + o3];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}.bindenv(this));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function GetTrade(InvenObj, pos) {
|
|||
|
|
local ptr = Memory.alloc(10240);
|
|||
|
|
Sq_CallFunc(S_Ptr("0x084FB918"), "int", ["pointer", "pointer", "int", "int"], ptr.C_Object, InvenObj.C_Object, 1, pos);
|
|||
|
|
return ptr.readS8();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
ProjectInitFuncMap.P_NpcTransaction <- NpcTransaction();
|