DP-S-Script/Dps_A/ProjectClass/NpcTransaction/NpcTransaction.nut

231 lines
8.6 KiB
Plaintext
Raw Normal View History

2025-11-03 21:13:01 +08:00
/*
文件名: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();