Commit 65b551a761130b66f81699f4e966643833d2286e

Authored by chenyueqi
1 parent 76c1102d

海港贸易季初版

src/ProtocolCode.lua
... ... @@ -241,6 +241,13 @@ actionCodes = {
241 241 Radio_startQuestRpc = 700,
242 242 Radio_finishQuestRpc = 701,
243 243 Radio_cancelQuestRpc = 702,
  244 +
  245 + Seaport_getServerProcessRpc = 750,
  246 + Seaport_donateRpc = 751,
  247 + Seaport_donateRewardRpc = 752,
  248 + Seaport_taskRpc = 753,
  249 + Seaport_shopRpc = 754,
  250 + Seaport_resetRpc = 755,
244 251 }
245 252  
246 253 rpcResponseBegin = 10000
... ...
src/RedisKeys.lua
... ... @@ -49,8 +49,8 @@ RANK_PVP_HIGHT = "rank:pvph"
49 49 RANK_PVP_HIGHT_KEY = {"rank:pvph1", "rank:pvph2"}
50 50 RECORD_PVP_HIGH = "record:pvph:%d"
51 51  
52   -
53   -
  52 +SEAPORT_TRADE_TASK_1 = "seaport:task1"
  53 +SEAPORT_TRADE_TASK_2 = "seaport:task2"
54 54  
55 55 FRIEND_KEY = "role:%d:friend" --哈希表 好友
56 56 FRIEND_APPLY_KEY = "role:%d:apply" -- sort set 申请列表
... ...
src/actions/RoleAction.lua
... ... @@ -159,6 +159,7 @@ function _M.loginRpc( agent, data )
159 159 role:changeStructVersion() -- 数据结构 版本更新
160 160 role:getAdvData(true) -- 清掉不合格的数据
161 161 role:advEndlessSeasonCheck(true) -- 冒险赛季更新检查
  162 + role:checkSeaportTrade() -- 检查海港贸易季活动
162 163  
163 164 -- 跨天登陆事件
164 165 local resetMode = role:updateTimeReset(now)
... ...
src/actions/SeaportAction.lua 0 → 100644
... ... @@ -0,0 +1,264 @@
  1 +local ipairs = ipairs
  2 +local table = table
  3 +local math = math
  4 +local redisproxy = redisproxy
  5 +local MsgPack = MsgPack
  6 +
  7 +local _M = {}
  8 +
  9 +function _M.getServerProcessRpc(agent, data)
  10 + local role = agent.role
  11 + local result = role:getSeaportServerProgress()
  12 +
  13 + SendPacket(actionCodes.Seaport_getServerProcessRpc, MsgPack.pack(result))
  14 + return true
  15 +end
  16 +
  17 +function _M.donateRpc(agent, data)
  18 + local role = agent.role
  19 + local msg = MsgPack.unpack(data)
  20 +
  21 + local phase = msg.phase or 0
  22 + local id = msg.id or 0
  23 + local itemId = msg.itemId or 0
  24 + local itemCount = msg.count or 0
  25 +
  26 + if itemId == 0 or itemCount == 0 then return 0 end
  27 + if role:getItemCount(itemId) < itemCount then return 1 end
  28 + local DonateCsv = csvdb["seaport_purchaseCsv"]
  29 + if DonateCsv[phase] or not DonateCsv[phase][id] then return 2 end
  30 +
  31 + local data = DonateCsv[phase][id]
  32 + local needs = data.need_item:toArray("=",true)
  33 + if itemId ~= needs[1] then return 3 end
  34 + if itemCount % needs[2] ~= 0 then return 4 end
  35 +
  36 + local group = itemCount / needs[2]
  37 + local rewards = data.award:toNumMap()
  38 +
  39 + for id, value in pairs(rewards) do
  40 + rewards[id] = value * group
  41 + end
  42 +
  43 + local rediskey = {SEAPORT_TRADE_TASK_1,SEAPORT_TRADE_TASK_2}
  44 + redisproxy:hincrby(rediskey[phase],id,itemCount)
  45 +
  46 + role:costItems({[itemId] = itemCount}, {log = {desc = "seaportDonate", int1 = phase, int2 = id}})
  47 + local reward, change = role:award(rewards, {log = {desc = "seaportDonate", int1 = data.phase, int2 = data.id}})
  48 +
  49 + role:mylog("role_action", {desc = "seaportDonate", int1 = itemId, int2 = itemCount})
  50 +
  51 + SendPacket(actionCodes.Seaport_donateRpc, MsgPack.pack(role:packReward(reward, change)))
  52 + return true
  53 +end
  54 +
  55 +function _M.donateRewardRpc(agent, data)
  56 + local role = agent.role
  57 + local msg = MsgPack.unpack(data)
  58 +
  59 + local id = msg.id
  60 + local dataCsv = csvdb["seaport_purchaseCsv"]
  61 + if not dataCsv[id] then return 0 end
  62 +
  63 + local seaport = role:getProperty("seaport") or {}
  64 + local donate = seaport.donate or {}
  65 + if donate[id] then return 3 end
  66 +
  67 + local data = dataCsv[id][1]
  68 +
  69 + local result = role:getSeaportServerProgress()
  70 + if not result[id] then return 1 end
  71 +
  72 + for _, tempData in ipairs(dataCsv[id]) do
  73 + if tempData.need_num > (result[id][tempData.id] or 0) then
  74 + return 2
  75 + end
  76 + end
  77 +
  78 + donate[id] = 1
  79 + seaport.donate = donate
  80 +
  81 + local reward, change = role:award(data.phase_award, {log = {desc = "seaportReward", int1 = data.phase, int2 = data.id}})
  82 +
  83 + role:updateProperty({field = "seaport", value = seaport})
  84 + SendPacket(actionCodes.Seaport_donateRewardRpc, MsgPack.pack(role:packReward(reward, change)))
  85 + return true
  86 +end
  87 +
  88 +-- 获取英雄大成功率
  89 +local function getHeroCoef(hero, condition)
  90 + -- 基础概率
  91 + local rareMap = {[HeroQuality.N] = 10, [HeroQuality.R] = 10, [HeroQuality.SR] = 15, [HeroQuality.SSR] = 20}
  92 + local rare = hero:getRare()
  93 + local result = 0
  94 + for _, it in ipairs(condition:toTableArray(true)) do
  95 + local type = it[1]
  96 + local value = it[2]
  97 + local add = it[3]
  98 + if type == 1 then -- 种族加成
  99 + if hero:getCamp() == value then
  100 + result = result + add
  101 + end
  102 + elseif type == 2 then -- 定位加成
  103 + if hero:getPosition() == value then
  104 + result = result + add
  105 + end
  106 + end
  107 + end
  108 +
  109 + return result + (rareMap[rare] or 0)
  110 +end
  111 +
  112 +function _M.taskRpc(agent, data)
  113 + local role = agent.role
  114 + local msg = MsgPack.unpack(data)
  115 +
  116 + local oper = msg.oper or 0
  117 + local team = msg.team or ""
  118 + local taskId = msg.id or 0
  119 + local level = msg.level or 0
  120 +
  121 + if oper == 0 then return 0 end
  122 + local TaskCsv = csvdb["seaport_taskCsv"]
  123 + if not TaskCsv[taskId] or not TaskCsv[taskId][level] then return 1 end
  124 +
  125 + local reward, change = {}, {}
  126 + local seaport = role:getProperty("seaport")
  127 +
  128 + local data = TaskCsv[taskId][level]
  129 + if oper == 1 then -- 开始委托
  130 + if team == "" then return 3 end
  131 + local conditions = data.conditions:toTableArray(true)
  132 + local heros = team:toNumMap()
  133 + local UnitCsv = csvdb["unitCsv"]
  134 + for _, conds in pairs(conditions) do
  135 + local count = 0
  136 + for _, heroId in pairs(heros) do
  137 + local hero = role.heros[heroId]
  138 + if not hero then return end
  139 +
  140 + if conds[1] == 1 then
  141 + if hero:getProperty("level") >= conds[2] then
  142 + count = count + 1
  143 + end
  144 + elseif conds[1] == 2 then
  145 + if UnitCsv[hero:getProperty("type")].rare >= conds[2] then
  146 + count = count + 1
  147 + end
  148 + elseif conds[1] == 3 then
  149 + count = count + 1
  150 + end
  151 + end
  152 + if count < conds[#conds] then
  153 + return 4
  154 + end
  155 + end
  156 +
  157 + local collect = seaport.collect or {}
  158 + collect[taskId] = {}
  159 + collect[taskId].time = skynet.timex()
  160 + collect[taskId].level = level
  161 + collect[taskId].team = team
  162 +
  163 + seaport.collect = collect
  164 + elseif oper == 2 then -- 领取委托奖励
  165 + local collects = seaport.collect or {}
  166 + local collect = collects[taskId] or {}
  167 + if not next(collects) or not next(collect) then
  168 + return 5
  169 + end
  170 + local endTime = data.time + collect.time
  171 + if endTime > skynet.timex() then return 6 end
  172 +
  173 + local carbonCsv = csvdb["idle_battleCsv"]
  174 + local expCarbonId = role:getProperty("hangInfo").expCarbonId
  175 + local coidCarbonId = role:getProperty("hangInfo").carbonId
  176 + if not carbonCsv[expCarbonId] or not expCarbonId[coidCarbonId] then return 7 end
  177 +
  178 + local totalCoef = 0
  179 + for _, heroId in ipairs(collect.team:toNumMap()) do
  180 + local hero = role.heros[heroId]
  181 + if hero then
  182 + totalCoef = totalCoef + getHeroCoef(hero, data.success)
  183 + hero:addHeroFaith(data.trust)
  184 + end
  185 + end
  186 +
  187 + local bigSuccess = false
  188 + local result = math.randomInt(0, 100)
  189 + if result < totalCoef then
  190 + bigSuccess = true
  191 + end
  192 +
  193 + local money = math.ceil(carbonCsv[coidCarbonId].money / 5 * data.time * carbonCsv[coidCarbonId].money_clear)
  194 + local exp = math.ceil(carbonCsv[expCarbonId].exp / 5 * data.time * carbonCsv[expCarbonId].exp_clear)
  195 + local itemReward = data.item_clear_special:toNumMap()
  196 + itemReward[ItemId.Gold] = (itemReward[ItemId.Gold] or 0) + money
  197 + itemReward[ItemId.Exp] = (itemReward[ItemId.Exp] or 0) + exp
  198 +
  199 + if bigSuccess then
  200 + for key, value in pairs(itemReward) do
  201 + itemReward[key] = math.ceil(1.5 * value)
  202 + end
  203 + end
  204 +
  205 + reward, change = role:award(itemReward, {log = {desc = "seaportTask", int1 = taskId, int2 = level}})
  206 +
  207 + seaport.collect[taskId] = nil
  208 + else
  209 + return 0
  210 + end
  211 +
  212 + role:updateProperty({field = "seaport", value = seaport})
  213 +
  214 + SendPacket(actionCodes.Seaport_taskRpc, MsgPack.pack(role:packReward(reward, change)))
  215 + return true
  216 +end
  217 +
  218 +function _M.shopRpc(agent, data)
  219 + local role = agent.role
  220 + local msg = MsgPack.unpack(data)
  221 + local id = msg.id or 0
  222 + local count = msg.count or 1
  223 +
  224 + local seaport = role:getProperty{"seaport"}
  225 + local shop = seaport.shop or {}
  226 +
  227 + if (shop[id] or 0) >= data.limit then return 1 end
  228 +
  229 + local shopCsv = {}
  230 + local dataSet = csvdb["shop_normalCsv"]
  231 + for _, data in pairs(dataSet) do
  232 + if data.shop == 5 then
  233 + shopCsv[data.id] = data
  234 + end
  235 + end
  236 +
  237 + local data = shopCsv[id]
  238 + if not data then return 2 end
  239 +
  240 + if role:getItemCount(data.icon) < data.cost * count then return 3 end
  241 +
  242 + role:costItems({[data.icon] = data.cost * count}, {log = {desc = "seaportShop", int1 = id, int2 = count}})
  243 +
  244 + local itemReward = data.gift:toNumMap()
  245 + for itemId, value in pairs(itemReward) do
  246 + itemReward[itemId] = value * count
  247 + end
  248 +
  249 + local reward, change = role:award(itemReward, {log = {desc = "seaportShop", int1 = id, int2 = count}})
  250 +
  251 + role:updateProperty({field = "seaport", value = seaport})
  252 +
  253 + SendPacket(actionCodes.Seaport_shopRpc, MsgPack.pack(role:packReward(reward, change)))
  254 + return true
  255 +end
  256 +
  257 +function _M.resetRpc(agent, data)
  258 + local role = agent.role
  259 + role:checkSeaportTrade()
  260 + SendPacket(actionCodes.Seaport_resetRpc, MsgPack.pack(""))
  261 + return true
  262 +end
  263 +
  264 +return _M
... ...
src/models/Role.lua
... ... @@ -188,6 +188,8 @@ Role.schema = {
188 188 calTask = {"table", {}}, -- 英雄令活动 日历任务活动
189 189 bcTask = {"table", {}}, -- 英雄令活动 日历任务活动 临时使用
190 190 radioTask = {"table", {}}, -- 电台任务 {id = {time=end_ts,heros=heros}} 表crusadeCsv
  191 +
  192 + seaport = {"table", {}}, -- 海岛贸易季 {time = 1234567890, donate = {}, collect = {[1] = {team = "1=2=3", time = 1234567890}}, shop = {}}
191 193 }
192 194  
193 195  
... ... @@ -418,6 +420,8 @@ function Role:data()
418 420 calTask = self:getProperty("calTask"),
419 421 bcTask = self:getProperty("bcTask"),
420 422 radioTask = self:getProperty("radioTask"),
  423 +
  424 + seaport = self:getProperty("seaport"),
421 425 }
422 426 end
423 427  
... ...
src/models/RoleLog.lua
... ... @@ -135,6 +135,11 @@ local ItemReason = {
135 135 --adv
136 136 chooseEvent = 1351, -- 冒险选择
137 137 clickTrader = 1352, -- 冒险商店
  138 +
  139 + seaportDonate = 1400, -- 贸易港捐赠
  140 + seaportShop = 1401, -- 贸易港商店兑换
  141 + seaportReward = 1402, -- 贸易港阶段奖励
  142 + seaportTask = 1403, -- 贸易港任务奖励
138 143 }
139 144  
140 145  
... ...
src/models/RolePlugin.lua
... ... @@ -1208,6 +1208,157 @@ function RolePlugin.bind(Role)
1208 1208 end
1209 1209 end
1210 1210  
  1211 + -- 结算上期海港贸易季
  1212 + function Role:checkSeaportTrade()
  1213 + local openTime0 = tonum(redisproxy:hget("autoincrement_set", "seaportTime0") or 0)
  1214 + local openTime1 = tonum(redisproxy:hget("autoincrement_set", "seaportTime1") or 0)
  1215 + local openTime2 = tonum(redisproxy:hget("autoincrement_set", "seaportTime2") or 0)
  1216 + local seaport = self:getProperty("seaport") or {}
  1217 + local oldTime = seaport.time or 0
  1218 + local update = false
  1219 +
  1220 + local function getReward(reset)
  1221 + -- 全服捐赠奖励
  1222 + local donate = seaport.donate or {}
  1223 + if not reset and (not donate[1] or not donate[2]) then
  1224 + local result = self:getSeaportServerProgress()
  1225 + local seaportCsv = csvdb["seaport_purchaseCsv"]
  1226 + for idx, set in ipairs(seaportCsv) do
  1227 + local done = true
  1228 + for id, data in ipairs(set) do
  1229 + if donate[id] or not result[idx] or not result[idx][id] or result[idx][id] < data.need_num then
  1230 + done = false
  1231 + break
  1232 + end
  1233 + end
  1234 + if done then
  1235 + update = true
  1236 + self:award(data.phase_award, {log = {desc = "seaportReward", int1 = set[1].phase, int2 = set[1].id}})
  1237 + donate[id] = 1
  1238 + end
  1239 + end
  1240 + seaport.donate = donate
  1241 + end
  1242 +
  1243 + -- 委托任务的奖励
  1244 + local collect = seaport.collect or {}
  1245 + if next(collect) then
  1246 + local function getHeroCoef(hero, condition)
  1247 + -- 基础概率
  1248 + local rareMap = {[HeroQuality.N] = 10, [HeroQuality.R] = 10, [HeroQuality.SR] = 15, [HeroQuality.SSR] = 20}
  1249 + local rare = hero:getRare()
  1250 + local result = 0
  1251 + for _, it in ipairs(condition:toTableArray(true)) do
  1252 + local type = it[1]
  1253 + local value = it[2]
  1254 + local add = it[3]
  1255 + if type == 1 then -- 种族加成
  1256 + if hero:getCamp() == value then
  1257 + result = result + add
  1258 + end
  1259 + elseif type == 2 then -- 定位加成
  1260 + if hero:getPosition() == value then
  1261 + result = result + add
  1262 + end
  1263 + end
  1264 + end
  1265 +
  1266 + return result + (rareMap[rare] or 0)
  1267 + end
  1268 +
  1269 + local carbonCsv = csvdb["idle_battleCsv"]
  1270 + local expCarbonId = self:getProperty("hangInfo").expCarbonId
  1271 + local coidCarbonId = self:getProperty("hangInfo").carbonId
  1272 + local taskCsv = csvdb["seaport_taskCsv"]
  1273 + local endTime = openTime0 + 86400 * 2
  1274 + for slot, set in pairs(taskCsv) do
  1275 + if collect[slot] then
  1276 + update = true
  1277 + local level = collect[slot].level
  1278 + local data = set[level]
  1279 + local teams = collect[slot].team
  1280 + local time = collect[slot].time
  1281 + if time + data.time <= endTime then
  1282 + if not carbonCsv[expCarbonId] or not expCarbonId[coidCarbonId] then return 7 end
  1283 +
  1284 + local totalCoef = 0
  1285 + for _, heroId in ipairs(teams:toNumMap()) do
  1286 + local hero = self.heros[heroId]
  1287 + if hero then
  1288 + totalCoef = totalCoef + getHeroCoef(hero, data.success)
  1289 + hero:addHeroFaith(data.trust)
  1290 + end
  1291 + end
  1292 +
  1293 + local bigSuccess = false
  1294 + local result = math.randomInt(0, 100)
  1295 + if result < totalCoef then
  1296 + bigSuccess = true
  1297 + end
  1298 +
  1299 + local money = math.ceil(carbonCsv[coidCarbonId].money / 5 * data.time * carbonCsv[coidCarbonId].money_clear)
  1300 + local exp = math.ceil(carbonCsv[expCarbonId].exp / 5 * data.time * carbonCsv[expCarbonId].exp_clear)
  1301 + local itemReward = data.item_clear_special:toNumMap()
  1302 + itemReward[ItemId.Gold] = (itemReward[ItemId.Gold] or 0) + money
  1303 + itemReward[ItemId.Exp] = (itemReward[ItemId.Exp] or 0) + exp
  1304 +
  1305 + if bigSuccess then
  1306 + for key, value in pairs(itemReward) do
  1307 + itemReward[key] = math.ceil(1.5 * value)
  1308 + end
  1309 + end
  1310 + self:award(itemReward, {log = {desc = "seaportTask", int1 = slot, int2 = level}})
  1311 + end
  1312 + end
  1313 + end
  1314 + end
  1315 + seaport.collect = {}
  1316 +
  1317 + if update or reset then
  1318 + if reset then
  1319 + seaport = {
  1320 + time = openTime0,
  1321 + shop = {},
  1322 + collect = {},
  1323 + donate = {}
  1324 + }
  1325 + end
  1326 + self:setProperty("seaport",seaport)
  1327 + end
  1328 + end
  1329 +
  1330 + if oldTime == openTime0 then
  1331 + if openTime1 == 1 or openTime2 == 1 then
  1332 + return
  1333 + end
  1334 + getReward()
  1335 + else
  1336 + getReward(true)
  1337 + end
  1338 + end
  1339 +
  1340 + function Role:getSeaportServerProgress()
  1341 + local result = {}
  1342 +
  1343 + local dataCsv = csvdb["seaport_purchaseCsv"]
  1344 + local rediskey = {SEAPORT_TRADE_TASK_1,SEAPORT_TRADE_TASK_2}
  1345 + for idx, set in ipairs(dataCsv) do
  1346 + local temp = {}
  1347 + temp = redisproxy:pipelining(function (red)
  1348 + for id, data in ipairs(set) do
  1349 + red:hget(rediskey[idx], id)
  1350 + end
  1351 + end)
  1352 + result[idx] = {}
  1353 + for i,v in ipairs(temp) do
  1354 + if v then
  1355 + result[idx][i] = v
  1356 + end
  1357 + end
  1358 + end
  1359 + return result
  1360 + end
  1361 +
1211 1362 -- 获得激活的冒险效果
1212 1363 function Role:getAdvActiveSupportEffect()
1213 1364 local effect = {}
... ...
src/services/globald.lua
... ... @@ -153,7 +153,31 @@ local function check_battle_act_close()
153 153 skynet.timeout(CHECK_BATTLE_ACT_CLOSE_INTERVAL, check_battle_act_close)
154 154 end
155 155  
  156 +-- @desc: 检查海港贸易开启、关闭
  157 +local function check_trade_seaport_status()
  158 + local delta = 1615579200 + 1000
  159 + local nowTime = delta or skynet.timex()
  160 + local nextTime = dayLater(nowTime)
  161 + local interval = nextTime - nowTime + 1
  162 +
  163 + local curTm = os.date("*t", nowTime)
  164 + if curTm.wday == 7 and curTm.hour == 4 then
  165 + redisproxy:hset("autoincrement_set", "seaportTime0", nowTime)
  166 + redisproxy:hset("autoincrement_set", "seaportTime1", 1)
  167 + redisproxy:del(SEAPORT_TRADE_TASK_1)
  168 + redisproxy:del(SEAPORT_TRADE_TASK_2)
  169 + end
  170 + if curTm.wday == 1 and curTm.hour == 4 then
  171 + redisproxy:hset("autoincrement_set", "seaportTime2", 1)
  172 + end
  173 + if curTm.wday == 2 and curTm.hour == 4 then
  174 + -- redisproxy:hset("autoincrement_set", "seaportTime0", 0)
  175 + redisproxy:hset("autoincrement_set", "seaportTime1", 0)
  176 + redisproxy:hset("autoincrement_set", "seaportTime2", 0)
  177 + end
156 178  
  179 + skynet.timeout(interval, check_trade_seaport_status)
  180 +end
157 181  
158 182 local CMD = {}
159 183  
... ... @@ -178,6 +202,7 @@ end
178 202 function CMD.start()
179 203 check_mail_queue()
180 204 --check_battle_act_close()
  205 + check_trade_seaport_status()
181 206 end
182 207  
183 208 local function __init__()
... ...