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(); |