Trade = {} local this = {} MINUTE_SECOND = 60 * 1000 TRADE_WAY = { GARD_BOSS = 1, -- 战盟boss SIEGE = 2, -- 攻城战 UNION = 3, -- 战盟 WORLD_UP = 4, -- 世界上架 SYSTEM_UP = 5, -- 系统上架 UNION_FLOW = 6, -- 战盟流拍 STALL = 7; -- 面对面商店 } TRADE_GOODS_TIPS = { SHOW = 1, -- 显示tips NO_SHOW = 0, -- 不显示 } TRADE_RECORD_TYPE = { PREORDER = 0, -- 预购 PURCHASE = 1, -- 购买 SALE = 2, -- 售出 } SORT_TYPE = { DEFAULT = 0, --默认 ASC_BY_TIME = 1, --按照时间升序 DESC_BY_TIME = 2, --按照时间降序 ASC_BY_PRICE = 3, --按照价格升序 DESC_BY_PRICE = 4, --按照价格降序 } TRADE_CAPACITY_GLOBAL_ID = 8001 SYS_TRADE_WORLD_GOODS = "R$tradeWorldGoods" ROLE_TRADE_WORLD_GOODS = "T$tradeWorldGoods" ROLE_TRADE_GOODS_RECORD = "T$tradeWorldRecord" ROLE_TRADE_PRE_GOODS = "T$tradeWorldPre" ---@class Trade.GoodInfo 世界商品信息 ---@field itemcfgid number 商品配置id ---@field itemid number 商品id ---@field itemname string 商品名字 ---@field entrysize number 词条属性数量 ---@field garde number 品质 ---@field ownid string 商品所属人id ---@field count number 商品数量 ---@field unitPrice number 商品单价 ---@field totalprice number 商品总价 ---@field job table 职业 ---@field cointype number 货币类型 ---@field publicitytime number 公示时间 ---@field upshelfduration number 竞拍时间 ---@field tax table 税率 ---@field subtype number 商品子类型 ---@field type number 商量类型 ---@field peroreder table 预购人员id ---@field publicitystatue boolean 是不是公示期间 ---@field listingtime number 上架时间 -- 世界交易行上架 -- msgData 中要包含 itemcfgid,bagindex,count,listingprice,totalprice,id function Trade.worldTradeListing(actor, msgData) --local isOpen, _ = PrivilegeMonth.hasPrivilege(actor, PrivilegeMonth.PrivilegeType.TRADE_SALE) --if not isOpen then -- noticeTip.noticeinfo(actor, StringIdConst.TEXT491) -- return --end local itemCfgId = msgData["itemcfgid"] local stallInfo = ConfigDataManager.getTable("cfg_stall", "id", itemCfgId, "way", TRADE_WAY.WORLD_UP) if not stallInfo and table.isEmpty(stallInfo) then noticeTip.noticeinfo(actor, StringIdConst.TEXT383) return end local have = this.checkCapacity(actor) if not have then noticeTip.noticeinfo(actor, StringIdConst.TEXT370) return end local itemStall = stallInfo[1] local jobTable = itemStall["job"] if not jobTable then jobTable = { 0 } elseif jobTable then jobTable = string.split(jobTable, "#") end local money = itemStall["money"] local ready = itemStall["ready"] local readyTime = tonumber(ready) * MINUTE_SECOND local time = itemStall["time"] local shellTime = tonumber(time) * MINUTE_SECOND local tax = itemStall["tax"] local taxTable = {} if not tax then taxTable = { 0, 0 } elseif tax then local taxInfo = string.split(tax, "|") for index, value in ipairs(taxInfo) do local taxDetail = string.split(value, "#") table.insert(taxTable, tonumber(taxDetail[2])) end end local subtypeItem = tonumber(itemStall["subtype"]) local typeItem = tonumber(itemStall["type"]) local itemInfo = getotheritemattinfo(actor,1,actor:toString(),msgData["id"]) jprint("上架道具信息",itemInfo) if table.isNullOrEmpty(itemInfo) then noticeTip.noticeinfo(actor, StringIdConst.TEXT371) return end local entries = itemInfo["entries"] local entryCount = 0 if not table.isNullOrEmpty(entries) then entryCount = table.count(entries) end ---type Trade.GoodInfo 世界商品信息 local goods = { itemcfgid = tonumber(msgData["itemcfgid"]), itemid = tonumber(itemInfo["itemid"]), garde = itemInfo["garde"] or 0, itemname = itemStall["name"], entrysize = entryCount, ownid = actor:toString(), count = tonumber(msgData["count"]), unitPrice = tonumber(msgData["listingprice"]), totalprice = tonumber(msgData["totalprice"]), job = jobTable, cointype = money, publicitytime = readyTime, upshelfduration = shellTime, tax = taxTable, subtype = subtypeItem, type = typeItem, peroreder = nil, publicitystatue = true, listingtime = getbaseinfo(actor,"now") } this.worldGoodsSave(actor, goods) local result = bagtoshell(actor, msgData) sendluamsg(actor, LuaMessageIdToClient.RES_TRADE_LISTING_GOODS, true) TaskHandler.TriggerTaskGoal(actor, TaskTargetType.TRADE_LINE_UP_GOODS, itemCfgId) end function clearqianghua(actor) -- jprint("开始执行清除数据") Trade.clearQiangHua() end function Trade.clearQiangHua() local allWorldGoods = getsysvar(SYS_TRADE_WORLD_GOODS) -- jprint("allWorldGoods",allWorldGoods) if table.isNullOrEmpty(allWorldGoods) then return end for actorString, roleAllGoods in pairs(allWorldGoods) do local actor = getactor(actorString) -- jprint("actor",actor) if actor ~= nil then local allequip = getplaydef(actor, "T$luaitemextdata") -- jprint("allequip",allequip) if not table.isNullOrEmpty(allequip) then for itemId, goods in pairs(roleAllGoods) do -- jprint("itemId",itemId) local itemInfo = allequip[tonumber(itemId)] -- jprint("itemInfo",itemInfo) if not table.isNullOrEmpty(itemInfo) then -- 下架商品 shelltobag(actor, actor:toString(), itemId, goods.count, actor:toString(), 0, "") roleAllGoods[tostring(itemId)] = nil end end end end allWorldGoods[actorString] = roleAllGoods end -- jprint("allWorldGoods",allWorldGoods) setsysvar(SYS_TRADE_WORLD_GOODS,allWorldGoods) end -- 保存上架商品 function this.worldGoodsSave(actor, goods) --local roleWorld = getplaydef(actor, ROLE_TRADE_WORLD_GOODS) --if not roleWorld then -- roleWorld = {} --end --roleWorld[tostring(goods.itemid)] = goods --setplaydef(actor, ROLE_TRADE_WORLD_GOODS, roleWorld) jprint("上架商品信息",goods) local allWorldGoods = getsysvar(actor, SYS_TRADE_WORLD_GOODS) if not allWorldGoods then allWorldGoods = {} end local roleAllGoods = allWorldGoods[actor:toString()] if not roleAllGoods then roleAllGoods = {} allWorldGoods[actor:toString()] = roleAllGoods end roleAllGoods[tostring(goods.itemid)] = goods jprint("全服玩家全部数据",roleAllGoods) setsysvar(actor, SYS_TRADE_WORLD_GOODS, allWorldGoods) end -- 交易行检查格子是否够用 function this.checkCapacity(actor) local capacity = ConfigDataManager.getTableValue("cfg_global", "value", "id", TRADE_CAPACITY_GLOBAL_ID) local is_has, count = PrivilegeMonth.hasPrivilege(actor, PrivilegeMonth.PrivilegeType.TRADE_LINE_UP_COUNT_INCREASE) capacity = capacity + count local allWorldGoods = getsysvar(actor, SYS_TRADE_WORLD_GOODS) if not allWorldGoods then return true end local count = 0 local roleAllGoods = allWorldGoods[actor:toString()] if roleAllGoods then count = table.count(roleAllGoods) end if count >= capacity then return false end return true end -- 下架商品 -- msgData 中要包含 itemcfgid,itemId function Trade.worldOffShelfGoods(actor, msgData) local itemId = msgData[2] local allWorldGoods = getsysvar(actor, SYS_TRADE_WORLD_GOODS) if not allWorldGoods then noticeTip.noticeinfo(actor, StringIdConst.TEXT372) return end local roleAllGoods = allWorldGoods[actor:toString()] local goodsDetail = roleAllGoods[tostring(itemId)] if not goodsDetail then noticeTip.noticeinfo(actor, StringIdConst.TEXT373) return end local publicityTime = goodsDetail.listingtime + goodsDetail.publicitytime local now = getbaseinfo("now") if now < publicityTime then noticeTip.noticeinfo(actor, StringIdConst.TEXT374) return end local ownid = goodsDetail.ownid if actor:toString() ~= tostring(ownid) then noticeTip.noticeinfo(actor, StringIdConst.TEXT375) return end local count = goodsDetail.count shelltobag(actor, actor:toString(), itemId, count, actor:toString(), 0, "") this.changeGoodsInfo(actor, itemId, count, count) sendluamsg(actor, LuaMessageIdToClient.RES_TRADE_OFF_GOODS, true) end -- lua中保存商品信息改变 function this.changeGoodsInfo(ownActor, goodId, itemCount, buyCount) local allWorldGoods = getsysvar(ownActor, SYS_TRADE_WORLD_GOODS) -- local tradeWorldGoodsInfo = getplaydef(ownActor, ROLE_TRADE_WORLD_GOODS) if itemCount == buyCount then local roleAllGoods = allWorldGoods[ownActor:toString()] roleAllGoods[tostring(goodId)] = nil setsysvar(ownActor, SYS_TRADE_WORLD_GOODS, allWorldGoods) elseif itemCount < buyCount then noticeTip.noticeinfo(actor, StringIdConst.TEXT376) return elseif itemCount > buyCount then local roleAllGoods = allWorldGoods[ownActor:toString()] local sysGoodDetail = roleAllGoods[tostring(goodId)] sysGoodDetail.count = itemCount - buyCount sysGoodDetail.totalprice = sysGoodDetail.count * sysGoodDetail.unitPrice setsysvar(ownActor, SYS_TRADE_WORLD_GOODS, allWorldGoods) end end -- 获取世界商品 function Trade.getTradeWorldGoods(actor, msgData) local allWorldGoods = getsysvar(actor, SYS_TRADE_WORLD_GOODS) Trade.flushWorldGoods() allWorldGoods = getsysvar(actor, SYS_TRADE_WORLD_GOODS) if not allWorldGoods then sendluamsg(actor, LuaMessageIdToClient.RES_GET_TRADE_GOODS, allWorldGoods) -- Trade.sendRecharge(actor) return end local goods = this.filterGoods(actor, allWorldGoods, msgData) -- local goods = getworldtradegoods(actor, msgData[1],msgData[2], msgData[3], msgData[4], msgData[5],msgData[6],TRADE_WAY.WORLD_UP) sendluamsg(actor, LuaMessageIdToClient.RES_GET_TRADE_GOODS, goods) -- Trade.sendRecharge(actor) end -- 过滤商品 function this.filterGoods(actor, allWorldGoods, msgData) local goods = {} if msgData[1] == 100 then this.publicityGoods(goods, msgData, allWorldGoods) return goods elseif msgData[1] == 200 then this.myPreGoods(actor, goods, msgData, allWorldGoods) -- Trade.getPreBuyGoods(actor,msgData) return goods end this.arrangeGoods(goods, msgData, allWorldGoods) return goods end -- 获取公示商品 function this.publicityGoods(goods, msgData, allWorldGoods) local now = getbaseinfo("now") for index, roleAllGoods in pairs(allWorldGoods) do for goodIndex, good in pairs(roleAllGoods) do local listingTime = good.listingtime local time = listingTime + good.publicitytime if now < time then local itemRank = ConfigDataManager.getTableValue("cfg_item", "rank", "id", good.itemCfgId) if (msgData[5] == 0 or itemRank == msgData[5]) and (msgData[6] == 0 or good.garde == msgData[6]) then if msgData[4] == 0 or good.job[1] == 0 or table.contains(good.job, tostring(msgData[4])) then good["publicity"] = 1 good["timename"] = "公示中" good["time"] = (time - now) / 1000 table.insert(goods, good) end end end end end end -- 预购商品 function this.myPreGoods(actor, goods, msgData, allWorldGoods) local preGoodInfo = getplaydef(actor, ROLE_TRADE_PRE_GOODS) if not preGoodInfo or not allWorldGoods then return end for index, preGood in pairs(preGoodInfo) do local roleAllGoods = allWorldGoods[preGood.rid] if roleAllGoods then local good = roleAllGoods[tostring(preGood.goodId)] if good then local itemRank = ConfigDataManager.getTableValue("cfg_item", "rank", "id", good.itemCfgId) if (msgData[1] == 0 or good.type == msgData[1]) and (msgData[2] == 0 or msgData[2] == good.subtype) and (msgData[5] == 0 or itemRank == msgData[5]) and (msgData[6] == 0 or good.garde == msgData[6]) then if msgData[4] == 0 or good.job[1] == 0 or table.contains(good.job, tostring(msgData[4])) then good["publicity"] = 1 good["timename"] = "公示中" good["time"] = (publicityTime - now) / 1000 table.insert(goods, good) end end end end end end -- 获取分类商品 function this.arrangeGoods(goods, msgData, allWorldGoods) local now = getbaseinfo("now") for index, roleAllGoods in pairs(allWorldGoods) do for index, good in pairs(roleAllGoods) do local itemRank = ConfigDataManager.getTableValue("cfg_item", "rank", "id", good.itemcfgid) if good and good.listingtime and good.publicitytime then local publicityTime = good.listingtime + good.publicitytime local offShelfTime = publicityTime + good.upshelfduration if (msgData[1] == 0 or good.type == msgData[1]) and (msgData[2] == 0 or msgData[2] == good.subtype) and (msgData[5] == 0 or tonumber(itemRank) == msgData[5]) and (msgData[6] == 0 or good.garde == msgData[6]) then if msgData[4] == 0 or good.job[1] == 0 or table.contains(good.job, tostring(msgData[4])) then -- local have = this.checkGood(allWorldGoods,good) if publicityTime > now then good["publicity"] = 1 good["timename"] = "公示中" good["time"] = (publicityTime - now) / 1000 elseif publicityTime < now and offShelfTime > now then good["publicity"] = 0 good["timename"] = "下架时间" good["time"] = (offShelfTime - now) / 1000 end table.insert(goods, good) end end end end end Trade.sortGoods(goods, msgData[3]) end -- 检查商品是否还在 function this.checkGood(allWorldGoods, good) local ownId = good.ownid local ownActor = getactor(ownId) local myListingGoods = getplaydef(ownActor, ROLE_TRADE_WORLD_GOODS) if not myListingGoods then shelltobag(ownActor, ownActor:toString(), good.itemid, good.count, ownActor:toString()) allWorldGoods[tostring(good.itemid)] = nil setsysvar(SYS_TRADE_WORLD_GOODS, allWorldGoods) return false end local myGood = myListingGoods[tostring(good.itemid)] if not myGood then shelltobag(ownActor, ownActor:toString(), good.itemid, good.count, ownActor:toString()) allWorldGoods[tostring(good.itemid)] = nil setsysvar(SYS_TRADE_WORLD_GOODS, allWorldGoods) return false end return true end -- 商品排序 function Trade.sortGoods(goods, type) if type == 0 then table.sort(goods, function(a, b) return a.listingtime < b.listingtime end) elseif type == SORT_TYPE.ASC_BY_TIME then table.sort(goods, function(a, b) return a.listingtime < b.listingtime end) elseif type == SORT_TYPE.DESC_BY_TIME then table.sort(goods, function(a, b) return a.listingtime > b.listingtime end) elseif type == SORT_TYPE.ASC_BY_PRICE then table.sort(goods, function(a, b) return a.totalprice < b.totalprice end) elseif type == SORT_TYPE.DESC_BY_PRICE then table.sort(goods, function(a, b) return a.totalprice > b.totalprice end) end end -- 购买世界交易行商品 -- msgData 中要包含 itemcfgid,itemId,type,count function Trade.bugWorldGoods(actor, msgData) local buyCount = msgData[4] local itemId = msgData[2] local goodRid = msgData[5] local goodActor = getactor(actor, goodRid) local allWorldGoods = getsysvar(goodActor, SYS_TRADE_WORLD_GOODS) if not allWorldGoods then noticeTip.noticeinfo(actor, StringIdConst.TEXT372) return end local roleAllGoods = allWorldGoods[tostring(goodRid)] if not roleAllGoods then noticeTip.noticeinfo(actor, StringIdConst.TEXT372) return end local goodsDetail = roleAllGoods[tostring(itemId)] if not goodsDetail then noticeTip.noticeinfo(actor, StringIdConst.TEXT373) return end local publicityTime = goodsDetail.listingtime + goodsDetail.publicitytime local now = getbaseinfo("now") if now < publicityTime then noticeTip.noticeinfo(actor, StringIdConst.TEXT377) return end local ownid = goodsDetail.ownid if actor:toString() == tostring(ownid) then noticeTip.noticeinfo(actor, StringIdConst.TEXT378) return end local unitPrice = goodsDetail.unitPrice local price = unitPrice * buyCount local cointype = goodsDetail.cointype local ownActor = getactor(actor, ownid) local itemCount = goodsDetail.count if tonumber(cointype) == 30030305 then local delete = MonthCard.deleteTime(actor, price) if not delete then return end else local haveCount = getbagitemcountbyid(actor, cointype) if haveCount < price then noticeTip.noticeinfo(actor, StringIdConst.TEXT379) return end removeitemfrombag(actor, cointype, price,0,9999,'交易行') end shelltobag(ownActor, ownid, itemId, buyCount, actor:toString(), 106004, goodsDetail.itemname) this.changeGoodsInfo(ownActor, itemId, itemCount, buyCount) local afterTaxPrice = this.calculationTax(ownActor, goodsDetail, buyCount) sendconfigmailbyrid(ownActor, ownid, 106011, { [tonumber(cointype)] = tonumber(afterTaxPrice) }, goodsDetail.itemname) this.saveTradeHistory(actor, TRADE_RECORD_TYPE.PURCHASE, goodsDetail, price) this.saveTradeHistory(ownActor, TRADE_RECORD_TYPE.SALE, goodsDetail, afterTaxPrice) sendluamsg(actor, LuaMessageIdToClient.RES_TRADE_BUY_GOODS, true) Trade.changeItemInfo(actor, ownid, itemId) end -- 计算税率 function this.calculationTax(ownActor, goodsDetail, count) local unitPrice = goodsDetail.unitPrice local totalPrice = unitPrice * count local table = goodsDetail.tax local tax = tonumber(table[1]) local has_vip, vip_rate = VipGiftPack.hasPrivilege(ownActor, VipPrivilege.Type.tax) if has_vip and string.tonumber(vip_rate) > 0 then tax = tax * (100 - tonumber(vip_rate)) / 100 tax = math.round(tax) end totalPrice = totalPrice * (100 - tax) / 100 totalPrice = math.round(totalPrice) local deleteCount = tonumber(table[2]) if has_vip then local addCount = math.round((deleteCount * tonumber(vip_rate)) / 100) deleteCount = deleteCount - addCount end totalPrice = totalPrice - deleteCount return totalPrice end -- 保存交易记录 function this.saveTradeHistory(actor, type, goodsDetail, totalPrice) local tradeRecorde = getplaydef(actor, ROLE_TRADE_GOODS_RECORD) if not tradeRecorde then tradeRecorde = {} end ---type Trade.Recorde 交易记录 local goodRecord = { itemname = goodsDetail.itemname, time = getbaseinfo("now"), tradetype = type, cointype = goodsDetail.cointype, price = totalPrice } if type == 2 then end table.insert(tradeRecorde, goodRecord) setplaydef(actor, ROLE_TRADE_GOODS_RECORD, tradeRecorde) end function cleartradehistory(actor) local tradeRecorde = getplaydef(actor, ROLE_TRADE_GOODS_RECORD) tradeRecorde = {} setplaydef(actor, tradeRecorde) end ---@class Trade.Recorde 交易记录 ---@field itemname string 商品名字 ---@field time number 成交时间 ---@field tradetype number 成交类型 ---@field cointype number 货币类型 ---@field price number 成交价格 -- 获取我的交易记录 function Trade.getWorldTradeRecord(actor) local tradeRecorde = getplaydef(actor, ROLE_TRADE_GOODS_RECORD) sendluamsg(actor, LuaMessageIdToClient.RES_TRADE_RECORD, tradeRecorde) end -- 获取我上架商品 function Trade.getWorldMyListing(actor) local listingGood = {} local capacity = ConfigDataManager.getTableValue("cfg_global", "value", "id", TRADE_CAPACITY_GLOBAL_ID) local is_has, count = PrivilegeMonth.hasPrivilege(actor, PrivilegeMonth.PrivilegeType.TRADE_LINE_UP_COUNT_INCREASE) capacity = capacity + count listingGood["capacity"] = capacity local allgoods = {} local stallInfo = Stall.getStallTimeInfo(actor) if not stallInfo then stallInfo = {} end sendluamsg(actor, LuaMessageIdToClient.RES_STALL_INFO, stallInfo) local allWorldGoods = getsysvar(actor, SYS_TRADE_WORLD_GOODS) if not allWorldGoods then local roleWorld = {} listingGood["number"] = 0 listingGood["allgoods"] = roleWorld sendluamsg(actor, LuaMessageIdToClient.RES_TRADE_MY_SHELVES, listingGood) -- noticeTip.noticeinfo(actor, StringIdConst.TEXT372) return end local roleWorld = allWorldGoods[actor:toString()] -- local roleWorld = getplaydef(actor, ROLE_TRADE_WORLD_GOODS) if not roleWorld then roleWorld = {} listingGood["number"] = 0 listingGood["allgoods"] = roleWorld sendluamsg(actor, LuaMessageIdToClient.RES_TRADE_MY_SHELVES, listingGood) return end local now = getbaseinfo("now") for index, good in pairs(roleWorld) do local publicityTime = good.listingtime + good.publicitytime local offShelfTime = publicityTime + good.upshelfduration if publicityTime > now then good["publicity"] = 1 good["timename"] = "公示中" good["time"] = (publicityTime - now) / 1000 elseif publicityTime < now and offShelfTime > now then good["publicity"] = 0 good["timename"] = "下架时间" good["time"] = (offShelfTime - now) / 1000 end table.insert(allgoods, good) end if allgoods then Trade.sortGoods(allgoods, 0) end listingGood["number"] = #allgoods listingGood["allgoods"] = allgoods jprint("listingGood",listingGood) sendluamsg(actor, LuaMessageIdToClient.RES_TRADE_MY_SHELVES, listingGood) end -- 预购商品 -- msgData 中要包含 itemcfgid,itemId,type function Trade.preWorldGoods(actor, msgData) local itemId = msgData[2] local goodRid = msgData[4] local goodActor = getactor(actor, goodRid) local allWorldGoods = getsysvar(goodActor, SYS_TRADE_WORLD_GOODS) if not allWorldGoods then noticeTip.noticeinfo(actor, StringIdConst.TEXT372) return end local roleAllGoods = allWorldGoods[tostring(goodRid)] if not roleAllGoods then noticeTip.noticeinfo(actor, StringIdConst.TEXT372) return end local goodsDetail = roleAllGoods[tostring(itemId)] if not goodsDetail then noticeTip.noticeinfo(actor, StringIdConst.TEXT373) return end local publicityTime = goodsDetail.listingtime + goodsDetail.publicitytime local now = getbaseinfo("now") if now > publicityTime then noticeTip.noticeinfo(actor, StringIdConst.TEXT380) return end local ownid = goodsDetail.ownid if actor:toString() == tostring(ownid) then noticeTip.noticeinfo(actor, StringIdConst.TEXT381) return end local peroreder = goodsDetail.peroreder if peroreder then for index, preRid in pairs(peroreder) do if tostring(preRid) == actor:toString() then noticeTip.noticeinfo(actor, StringIdConst.TEXT382) return end end end local totalprice = goodsDetail.totalprice local cointype = goodsDetail.cointype if tonumber(cointype) == 30030305 then local delete = MonthCard.deleteTime(actor, totalprice) if not delete then return end else local haveCount = getbagitemcountbyid(actor, cointype) if haveCount < totalprice then noticeTip.noticeinfo(actor, StringIdConst.TEXT379) return end removeitemfrombag(actor, cointype, totalprice,0,9999,'交易行') end this.addPre(goodActor, itemId, goodRid, actor) local preGoodInfo = getplaydef(actor, ROLE_TRADE_PRE_GOODS) if not preGoodInfo then preGoodInfo = {} end local perGoodInfo = { rid = goodRid, goodId = itemId } table.insert(preGoodInfo, perGoodInfo) setplaydef(actor, ROLE_TRADE_PRE_GOODS, preGoodInfo) this.saveTradeHistory(actor, TRADE_RECORD_TYPE.PREORDER, goodsDetail, totalprice) sendluamsg(actor, LuaMessageIdToClient.RES_TRADE_PRE_ORDER, true) end -- 商品中添加预购信息 function this.addPre(actor, goodId, goodRid, preActor) local allWorldGoods = getsysvar(actor, SYS_TRADE_WORLD_GOODS) local roleAllGoods = allWorldGoods[tostring(goodRid)] local goodsDetail = roleAllGoods[tostring(goodId)] local peroreder = goodsDetail.peroreder if not peroreder then peroreder = {} end table.insert(peroreder, preActor:toString()) goodsDetail.peroreder = peroreder -- allWorldGoods[tostring(goodId)] = goodsDetail setsysvar(actor, SYS_TRADE_WORLD_GOODS, allWorldGoods) --local ownid = goodsDetail.ownid --local ownActor = getactor(actor, ownid) --local myListingGoods = getplaydef(ownActor, ROLE_TRADE_WORLD_GOODS) --local detail = myListingGoods[tostring(goodId)] --local goodPre = detail.peroreder --if not goodPre then -- goodPre = {} --end --table.insert(goodPre, actor:toString()) --detail.peroreder = goodPre --myListingGoods[tostring(goodId)] = detail --setplaydef(ownActor, ROLE_TRADE_WORLD_GOODS, myListingGoods) end -- 交易行刷新 function Trade.flushWorldGoods() local serverType = getbaseinfo("servertype") if serverType == 2 then -- 跨服服务器不执行 return end local allWorldGoods = getsysvar(SYS_TRADE_WORLD_GOODS) if not allWorldGoods then return end local now = getbaseinfo("now") for index, roleAllGoods in pairs(allWorldGoods) do for index, good in pairs(roleAllGoods) do if good and good.listingtime and good.publicitytime then local publicityTime = good.listingtime + good.publicitytime local offShelfTime = publicityTime + good.upshelfduration if now > publicityTime and now < offShelfTime and good.publicitystatue then local peroreder = good.peroreder if not peroreder then this.changeGoodState(good, roleAllGoods) elseif peroreder then this.handlePre(good, roleAllGoods) end elseif offShelfTime < now then this.flowFilming(good, roleAllGoods) end end end end setsysvar(SYS_TRADE_WORLD_GOODS, allWorldGoods) end -- 合服时下架所有商品 function Trade.combineglobalvar(varName,varData) gameDebug.print("合服时交易行全部商品信息", varData) for index, allWorldGoods in pairs(varData) do if not table.isEmpty(allWorldGoods) then for index, roleAllGoods in pairs(allWorldGoods) do for index, good in pairs(roleAllGoods) do if not table.isEmpty(good) then local peroreder = good.peroreder if table.isEmpty(peroreder) then this.flowFilming(good, roleAllGoods) else this.handlePre(good, roleAllGoods) end end end end end end setsysvar(SYS_TRADE_WORLD_GOODS, {}) end -- 清理交易行脏数据 function cleartradedata(actor) setsysvar(actor, SYS_TRADE_WORLD_GOODS,{}) end -- 改变商品状态(公示状态改成竞拍) function this.changeGoodState(good, allWorldGoods) local ownId = good.ownid local ownActor = getactor(ownId) local allWorldGood = getsysvar(ownActor, SYS_TRADE_WORLD_GOODS) local myListingGoods = allWorldGood[ownActor:toString()] if not myListingGoods then return end local myGoodInfo = myListingGoods[tostring(good.itemid)] myGoodInfo.publicitystatue = false myListingGoods[tostring(good.itemid)] = myGoodInfo allWorldGood[ownActor:toString()] = myListingGoods setsysvar(ownActor, SYS_TRADE_WORLD_GOODS, allWorldGood) end -- 处理预购商品 function this.handlePre(good, roleAllGoods) local peroreder = good.peroreder local successIndex = math.random(1, #peroreder) local successRid = peroreder[successIndex] local ownActor = getactor(good.ownid) local goodId = good.itemid -- 清理预购人员存储的信息 for index, preRid in pairs(peroreder) do if tostring(successRid) ~= tostring(preRid) then local preActor = getactor(preRid) local myPreInfo = getplaydef(preActor, ROLE_TRADE_PRE_GOODS) if not table.isEmpty(myPreInfo) then local preIndex = this.findPreInfo(myPreInfo, tostring(goodId), tostring(good.ownid)) if preIndex then table.remove(myPreInfo, preIndex) setplaydef(preActor, ROLE_TRADE_PRE_GOODS, myPreInfo) end end if tonumber(good.cointype) == 30030305 then MonthCard.addTime(ownActor, good.totalprice) else sendconfigmailbyrid(ownActor, preRid, 106006, { [tonumber(good.cointype)] = tonumber(good.totalprice) }, good.itemname .. "#" .. "货币") end end end local successActor = getactor(successRid) -- this.changeGoodsInfo(ownActor,itemId,itemCount,buyCount) local afterTaxPrice = this.calculationTax(ownActor, good, good.count) sendconfigmailbyrid(ownActor, good.ownid, 106011, { [tonumber(good.cointype)] = tonumber(afterTaxPrice) }, good.itemname) shelltobag(ownActor, good.ownid, goodId, good.count, successRid, 106004, good.itemname) roleAllGoods[tostring(good.itemid)] = nil -- this.saveTradeHistory(actor,TRADE_RECORD_TYPE.PURCHASE,goodsDetail,price) this.saveTradeHistory(ownActor, TRADE_RECORD_TYPE.SALE, good, afterTaxPrice) Trade.changeItemInfo(successActor, good.ownid, goodId) end -- 获取预购商品索引 function this.findPreInfo(myPreInfo, goodId, rid) for index, preInfo in pairs(myPreInfo) do if tostring(preInfo.goodId) == tostring(goodId) and tostring(preInfo.rid) == tostring(rid) then return index end end end -- 商品流拍 function this.flowFilming(good, roleAllGoods) local ownId = good.ownid local ownActor = getactor(ownId) if not roleAllGoods then return end shelltobag(ownActor, ownActor:toString(), good.itemid, good.count, ownActor:toString()) roleAllGoods[tostring(good.itemid)] = nil end -- 发送充值消息 function Trade.sendRecharge(actor) local allRechargeInfo = getsysvar(actor, SYS_RECHARGE_INFO) if table.isEmpty(allRechargeInfo) then allRechargeInfo = {} end local rechargeInfo = allRechargeInfo[actor:toString()] sendluamsg(actor, LuaMessageIdToClient.RES_RECHARGE_TRADE_INFO, rechargeInfo) end -- 午夜刷新重置记录 function Trade.serverMiddleNight() local allRechargeInfo = getsysvar(SYS_RECHARGE_INFO) if table.isEmpty(allRechargeInfo) then return end local now = getbaseinfo("now") for index, roleRechargeInfo in pairs(allRechargeInfo) do local actor = getactor(index) local rechargeGear = ConfigDataManager.getTable("cfg_lines", "id", roleRechargeInfo.gearPosition) if rechargeGear then local currentGearInfo = rechargeGear[1] local decayTime = tonumber(currentGearInfo.decaytime) local lsatGearChangeTime = roleRechargeInfo.lsatGearChangeTime local decay = lsatGearChangeTime + decayTime * 24 * 60 * MINUTE_SECOND if decay < now then -- 降档处理 local decayGears = tonumber(currentGearInfo.decaygears) if roleRechargeInfo.gearPosition ~= 1 then roleRechargeInfo.gearPosition = decayGears roleRechargeInfo.lsatGearChangeTime = now local limit = this.calculationGearMaxLimit(nil, decayGears) roleRechargeInfo.upperLimit = limit end roleRechargeInfo.quit = true roleRechargeInfo.gearRecharge = 0 if tonumber(currentGearInfo.decaytime) > 1 then roleRechargeInfo.bubble = false else roleRechargeInfo.bubble = true end else -- 不降档位检查是否要显示气泡 local time = lsatGearChangeTime + (decayTime - 1) * 24 * 60 * MINUTE_SECOND if time < now then roleRechargeInfo.bubble = true else roleRechargeInfo.bubble = false end end roleRechargeInfo.cost = 0 allRechargeInfo[index] = roleRechargeInfo end sendluamsg(actor, LuaMessageIdToClient.RES_RECHARGE_TRADE_INFO, roleRechargeInfo) end setsysvar(SYS_RECHARGE_INFO, allRechargeInfo) end ---@class recharge 充值记录 ---@field totalRecharge number 总共充值金额 ---@field lastRechargeTime number 上次充值时间(毫秒时间戳) ---@field gearPosition number 当前档位 ---@field gearRecharge number 档位充值金额 ---@field quit boolean 是否退档 ---@field lsatGearChangeTime number 重置档位时间 ---@field cost number 花费额度 ---@field upperLimit number 额度上限 ---@field bubble boolean 是否显示气泡 SYS_RECHARGE_INFO = "R$rechargeInfo" function tsetrechargegear(actor) Trade.recharge(actor, 1) end -- 检查当前额度是否够 function Trade.checkCost(actor, price) local allRechargeInfo = getsysvar(actor, SYS_RECHARGE_INFO) if table.isEmpty(allRechargeInfo) then allRechargeInfo = {} end local rechargeInfo = allRechargeInfo[actor:toString()] if table.isEmpty(rechargeInfo) then noticeTip.noticeinfo(actor, StringIdConst.TEXT462) return false end local cost = rechargeInfo.cost local upperLimit = rechargeInfo.upperLimit if upperLimit >= cost + price then return true else noticeTip.noticeinfo(actor, StringIdConst.TEXT462) return false end end -- 增加花费 function Trade.addCost(actor, price) local allRechargeInfo = getsysvar(actor, SYS_RECHARGE_INFO) if table.isEmpty(allRechargeInfo) then allRechargeInfo = {} end local rechargeInfo = allRechargeInfo[actor:toString()] if table.isEmpty(rechargeInfo) then return end rechargeInfo.cost = rechargeInfo.cost + price allRechargeInfo[actor:toString()] = rechargeInfo setsysvar(actor, SYS_RECHARGE_INFO, allRechargeInfo) end -- 减少花费 function Trade.deleteCost(actor, price) local allRechargeInfo = getsysvar(actor, SYS_RECHARGE_INFO) if table.isEmpty(allRechargeInfo) then allRechargeInfo = {} end local rechargeInfo = allRechargeInfo[actor:toString()] if table.isEmpty(rechargeInfo) then return end if rechargeInfo.cost > price then rechargeInfo.cost = rechargeInfo.cost - price else rechargeInfo.cost = 0 end allRechargeInfo[actor:toString()] = rechargeInfo setsysvar(actor, SYS_RECHARGE_INFO, allRechargeInfo) end -- 更新充值信息 function Trade.recharge(actor, cfg, count, amount, ext, outRewards) local allRechargeInfo = getsysvar(actor, SYS_RECHARGE_INFO) if table.isEmpty(allRechargeInfo) then allRechargeInfo = {} end local rechargeInfo = allRechargeInfo[actor:toString()] if table.isEmpty(rechargeInfo) then rechargeInfo = { totalRecharge = amount, lastRechargeTime = getbaseinfo(actor, "now"), gearPosition = this.getRechargeGear(actor, amount), gearRecharge = 0, quit = false, lsatGearChangeTime = getbaseinfo(actor, "now"), cost = 0, upperLimit = 0, bubble = false } local upperLimit = this.calculationUpperLimit(actor, rechargeInfo.gearPosition, rechargeInfo.totalRecharge, rechargeInfo.quit) rechargeInfo.upperLimit = upperLimit allRechargeInfo[actor:toString()] = rechargeInfo setsysvar(actor, SYS_RECHARGE_INFO, allRechargeInfo) sendluamsg(actor, LuaMessageIdToClient.RES_RECHARGE_TRADE_INFO, rechargeInfo) return end -- 已经充值过逻辑处理 rechargeInfo.totalRecharge = rechargeInfo.totalRecharge + amount rechargeInfo.lastRechargeTime = getbaseinfo(actor, "now") local gearPosition = rechargeInfo.gearPosition local rechargeGear = ConfigDataManager.getTable("cfg_lines", "id", gearPosition) if not rechargeGear then -- error("当前充值档位出现错误") return end local gearInfo = rechargeGear[1] local activationRecharge = tonumber(gearInfo.activationrecharge) local allRecharge = rechargeInfo.gearRecharge + amount if rechargeInfo.quit then -- 有退档现象,检查是否可以提升档位 if allRecharge >= activationRecharge then -- 可以提升档位 local maxGear = this.getRechargeGear(actor, rechargeInfo.totalRecharge) rechargeInfo.gearPosition = maxGear rechargeInfo.gearRecharge = 0 rechargeInfo.quit = false local upperLimit = this.calculationUpperLimit(actor, maxGear, rechargeInfo.totalRecharge, false) rechargeInfo.upperLimit = upperLimit else -- 不能提升档位 rechargeInfo.gearRecharge = rechargeInfo.gearRecharge + amount end else -- 没有发生过退档 if allRecharge >= activationRecharge then -- 可以提升档位 local maxGear = this.getRechargeGear(actor, rechargeInfo.totalRecharge) rechargeInfo.gearPosition = maxGear rechargeInfo.gearRecharge = 0 rechargeInfo.quit = false else -- 不能提升档位 rechargeInfo.gearRecharge = rechargeInfo.gearRecharge + amount end local upperLimit = this.calculationUpperLimit(actor, rechargeInfo.gearPosition, rechargeInfo.totalRecharge, false) rechargeInfo.upperLimit = upperLimit end rechargeInfo.lsatGearChangeTime = getbaseinfo(actor, "now") rechargeInfo.bubble = false allRechargeInfo[actor:toString()] = rechargeInfo setsysvar(actor, SYS_RECHARGE_INFO, allRechargeInfo) -- 发送lua信息 sendluamsg(actor, LuaMessageIdToClient.RES_RECHARGE_TRADE_INFO, rechargeInfo) end -- 获取充值最高档位 function this.getRechargeGear(actor, totalRecharge) local rechargeGear = ConfigDataManager.getTable("cfg_lines") if table.isEmpty(rechargeGear) then return 0 end local maxGear = 0 for index, gear in pairs(rechargeGear) do local interval = gear.interval local intervalTable = string.split(interval, "#") local minRecharge = tonumber(intervalTable[1]) local maxRecharge = tonumber(intervalTable[2]) if tonumber(gear.id) > maxGear then maxGear = tonumber(gear.id) end if totalRecharge >= minRecharge and totalRecharge <= maxRecharge then return tonumber(gear.id) end end return maxGear end -- 计算额度上限. function this.calculationUpperLimit(actor, gear, totalRecharge, quit) if quit then return this.calculationGearMaxLimit(actor, gear) else return this.calculationAllMaxLimit(actor, gear, totalRecharge) end end -- 计算档位的最大限额 function this.calculationGearMaxLimit(actor, currentGear) if currentGear < 1 then return 0 end local rechargeGear = ConfigDataManager.getTable("cfg_lines") if table.isEmpty(rechargeGear) then return 0 end local limit = 0 for index, gear in pairs(rechargeGear) do if currentGear >= tonumber(gear.id) then local interval = gear.interval local intervalTable = string.split(interval, "#") local minRecharge = tonumber(intervalTable[1]) local maxRecharge = tonumber(intervalTable[2]) local each = tonumber(gear.each) local quotaLimit = tonumber(gear.quotalimit) local gearLimit = math.ceil((maxRecharge - minRecharge + 1) / each) * quotaLimit limit = limit + gearLimit end end return limit end -- 计算总共充值的最大额度 function this.calculationAllMaxLimit(actor, currentGear, totalRecharge) local rechargeGear = ConfigDataManager.getTable("cfg_lines", "id", currentGear) if table.isEmpty(rechargeGear) then -- error("当前充值档位出现错误") end local currentGearInfo = rechargeGear[1] local interval = currentGearInfo.interval local intervalTable = string.split(interval, "#") local minRecharge = tonumber(intervalTable[1]) local each = tonumber(currentGearInfo.each) local quotaLimit = tonumber(currentGearInfo.quotalimit) local currentPrice = totalRecharge - minRecharge + 1 local gearLimit = math.ceil(currentPrice / each) * quotaLimit local gear = currentGear - 1 local allLimit = this.calculationGearMaxLimit(actor, gear) return gearLimit + allLimit end -- ------------------------------旧方法------------------------------------------------------------------------ -- 战盟boss上架交易行 function Trade.unionListGoods(actor, activityId, closetDay, listingGoods, myHurtMember, allianceId) for index, goods in pairs(listingGoods) do local itemCfgId = goods["itemcfgid"] local stallInfo = ConfigDataManager.getTable("cfg_stall", "id", itemCfgId, "startday", closetDay, "way", TRADE_WAY.GARD_BOSS) if not stallInfo then noticeTip.noticeinfo(actor, StringIdConst.TEXT383) return end local itemStall = stallInfo[1] local job = itemStall["job"] goods["job"] = job local time = itemStall["time"] goods["time"] = time local money = itemStall["money"] goods["money"] = money local fixedPrice = itemStall["fixedprice"] goods["fixedPrice"] = fixedPrice local startingPrice = itemStall["startingprice"] goods["startingPrice"] = startingPrice local auction = itemStall["auction"] goods["auction"] = auction local type = itemStall["type"] local subtype = itemStall["subtype"] goods["type"] = type goods["subtype"] = subtype goods["position"] = tostring(TRADE_WAY.GARD_BOSS) end uniontradelisting(actor, activityId, listingGoods, myHurtMember, allianceId) end -- 战盟boss竞价 function unionListGoods(actor, activityId, listingGoods) for index, goods in pairs(listingGoods) do local itemCfgId = goods["itemcfgid"] local stallInfo = ConfigDataManager.getTable("cfg_stall", "id", itemCfgId, "way", TRADE_WAY.GARD_BOSS) if not stallInfo then noticeTip.noticeinfo(actor, StringIdConst.TEXT383) return end local itemStall = stallInfo[1] local job = itemStall["job"] goods["job"] = job local money = itemStall["money"] goods["money"] = money local fixedPrice = itemStall["fixedPrice"] goods["fixedPrice"] = fixedPrice local startingPrice = itemStall["startingPrice"] goods["startingPrice"] = startingPrice local auction = itemStall["auction"] goods["auction"] = auction local type = itemStall["type"] local subtype = itemStall["subtype"] goods["type"] = type goods["subtype"] = subtype goods["position"] = tostring(TRADE_WAY.GARD_BOSS) end uniontradelisting(actor, activityId, listingGoods) end -- 获取世界商品 商品配置id 商品id function Trade.getGoodsInfo(actor, msgData) -- jprint("msgData",msgData) local ownActor = getactor(actor, msgData[2]) goodsdetailinfo(ownActor, msgData[1], TRADE_WAY.WORLD_UP, actor:toString()) end -- 购买成功后交换lua中存储的道具信息 function Trade.changeItemInfo(actor, ownId, itemId) local ownActor = getactor(actor, ownId) local allequip = getplaydef(ownActor, "T$luaitemextdata") if not allequip then return end local equipext = allequip[itemId] if not equipext then return end local allEquipActor = getplaydef(actor, "T$luaitemextdata") if not allEquipActor then allEquipActor = {} end allEquipActor[itemId] = equipext -- EquipAndAppear.SetItemExtData(actor, itemId, equipext) setplaydef(actor, "T$luaitemextdata", allEquipActor) allequip[itemId] = nil setplaydef(ownActor, "T$luaitemextdata", allequip) end function getroletet(actor) local actorId = getactor(actor,"18023607160522752") local name = getbaseinfo(actorId,"rolename") jprint("name",name) end local TRADE_DATA_REPAIR = "T$_TRADE_DATA_REPAIR" function Trade.login(actor) RepairRoleData.action(actor, TRADE_DATA_REPAIR, 20250115, this.TradeDataRepair_2025_01_15, actor) end function this.TradeDataRepair_2025_01_15(actor) local allWorldGoods = getsysvar(actor, SYS_TRADE_WORLD_GOODS) if table.isNullOrEmpty(allWorldGoods) then shellclean(actor) return end local roleWorld = allWorldGoods[actor:toString()] if table.isNullOrEmpty(roleWorld) then shellclean(actor) return end local allItemId = {} for index, good in pairs(roleWorld) do local itemId = good.itemid table.insert(allItemId, itemId) end shellclean(actor,allItemId) end --TODO 一定要放到文件最后 --注册充值事件 -- RechargeEventListerTable:eventLister("0", "交易行", Trade.recharge)