Commit 29fbbc107198caddd83ac840010f164906233d5c

Authored by zhouhaihai
1 parent 243bf75b

夜间打工

src/GlobalVar.lua
... ... @@ -16,6 +16,12 @@ TIME_ZONE = math.floor(os.difftime(START_RESET_TIME_BASE, os.time(os.date("!*t",
16 16  
17 17 START_RESET_TIME = START_RESET_TIME_BASE - TIME_ZONE * 3600
18 18  
  19 +function weekday(now)
  20 + local day = math.ceil((now - START_RESET_TIME) % 604800 / 86400)
  21 + if day == 0 then day = 1 end
  22 + return day
  23 +end
  24 +
19 25 STRUCT_VERSION = 3 -- 数据结构版本
20 26  
21 27 MAX_ROLE_NUM = 1000000
... ... @@ -155,6 +161,11 @@ TimeReset = {
155 161 DrawType1 = 17, -- 变异 抽卡加成
156 162 DrawType2 = 18, -- 通常 抽卡加成
157 163 DrawType3 = 19, -- 魔法 抽卡加成
  164 + WorkBattle1 = 22, -- 夜间玩法 1
  165 + WorkBattle2 = 23, -- 夜间玩法 2
  166 + WorkBattle3 = 24, -- 夜间玩法 3
  167 + WorkBattle4 = 25, -- 夜间玩法 4
  168 + WorkBattle5 = 26, -- 夜间玩法 5
158 169 }
159 170  
160 171 -- TimeReset 索引数组
... ...
src/ProtocolCode.lua
... ... @@ -121,6 +121,10 @@ actionCodes = {
121 121 Hang_bagFieldRpc = 263,
122 122 Hang_chatLineRpc = 264,
123 123 Hang_selectTeamRpc = 265,
  124 + Hang_startWorkBattleRpc = 266,
  125 + Hang_endWorkBattleRpc = 267,
  126 + Hang_workBattleInfoRpc = 268,
  127 + Hang_getWorkRewardRpc = 269,
124 128  
125 129 Diner_updateProperty = 300,
126 130 Diner_addSellRpc = 301,
... ...
src/RedisKeys.lua
... ... @@ -62,7 +62,7 @@ FRIEND_ENERGY = "role:%d:energy" -- set 送给我活动能量的好友
62 62 FRIEND_RECOMMEND = "friend:recommend" -- sort set 登录排序 获取推荐好友
63 63 CHAT_OFFLINE = "chat:offline:%d" --消息离线缓存
64 64  
65   -
  65 +WORK_BATTLE_COUNT = "global:workbattle" -- 世界次数统计
66 66 -- FRIEND_DINER_LIKE_KEY = "role:%d:diner:like" -- list
67 67  
68 68 -- UNION_SET = "global:union"
... ...
src/actions/HangAction.lua
... ... @@ -750,6 +750,260 @@ function _M.endBonusBattleRpc(agent, data)
750 750 return true
751 751 end
752 752  
  753 +
  754 +
  755 +local function workWinReward(role, bonusData, rewardType, count, sweep)
  756 + count = count or 1
  757 + local reward, change = {}
  758 + if rewardType == 2 or rewardType == 4 then
  759 + for k, v in pairs(bonusData.perfect_reward:toNumMap()) do
  760 + reward[k] = (reward[k] or 0) + v
  761 + end
  762 + end
  763 +
  764 + if rewardType == 3 then
  765 + reward = bonusData.reward:toNumMap()
  766 + for itemId, c in pairs(reward) do
  767 + reward[itemId] = c * count
  768 + end
  769 + for i = 1, count do
  770 + local chance = bonusData.chance:randWeight(true)
  771 + if chance[1] ~= 0 then
  772 + reward[chance[1]] = (reward[chance[1]] or 0) + chance[2]
  773 + end
  774 + end
  775 + end
  776 + if sweep then
  777 + -- local bnousReward = role:getBnousSweep()
  778 + -- for key, value in pairs(bnousReward) do
  779 + -- reward[key] = (reward[key] or 0) + value * count
  780 + -- end
  781 + end
  782 +
  783 + reward, change = role:award(reward, {log = {desc = "workBattle", int1 = bonusData.id}})
  784 + -- role:checkTaskEnter("BonusPass", {id = bonusData.id, count = count})
  785 + return reward, change
  786 +end
  787 +
  788 +function _M.workBattleInfoRpc(agent, data)
  789 + local role = agent.role
  790 + local msg = MsgPack.unpack(data)
  791 + local workMainCsv = csvdb["work_mainCsv"][msg.type]
  792 + if not workMainCsv then return 1 end
  793 + if not role:isTimeResetOpen(TimeReset["WorkBattle" .. msg.type]) then return 2 end
  794 + SendPacket(actionCodes.Hang_workBattleInfoRpc, MsgPack.pack({count = tonum(redisproxy:hget(WORK_BATTLE_COUNT, role:getTimeResetRound(TimeReset["WorkBattle" .. msg.type]) * 10 + msg.type))}))
  795 + return true
  796 +end
  797 +
  798 +
  799 +function _M.getWorkRewardRpc(agent, data)
  800 + local role = agent.role
  801 + local msg = MsgPack.unpack(data)
  802 + local workMainCsv = csvdb["work_mainCsv"][msg.type]
  803 + if not workMainCsv then return 1 end
  804 + if not role:isTimeResetOpen(TimeReset["WorkBattle" .. msg.type]) then return 2 end
  805 + local count = tonum(redisproxy:hget(WORK_BATTLE_COUNT, role:getTimeResetRound(TimeReset["WorkBattle" .. msg.type]) * 10 + msg.type))
  806 + if count < workMainCsv.target_num then return 3 end
  807 + local workBattle = role:getProperty("workBattle")
  808 + if workBattle[msg.type] ~= 1 then
  809 + return 4
  810 + end
  811 + workBattle[msg.type] = -1
  812 + role:updateProperty({field = "workBattle", value = workBattle})
  813 + local reward, change = role:award(workMainCsv.phase_award, {log = {desc = "workReward"}})
  814 + SendPacket(actionCodes.Hang_getWorkRewardRpc, MsgPack.pack({reward = reward, change = change}))
  815 + return true
  816 +end
  817 +
  818 +function _M.startWorkBattleRpc(agent, data)
  819 + local role = agent.role
  820 + local msg = MsgPack.unpack(data)
  821 + local id = msg.id
  822 + local count = msg.count or 1
  823 +
  824 + if not role:isFuncUnlock(FuncUnlock.BonusBattle) then return 1 end
  825 +
  826 + local bonusData = csvdb["work_battleCsv"][id]
  827 +
  828 + if not bonusData then return 3 end
  829 +
  830 + if not role:isTimeResetOpen(TimeReset["WorkBattle" .. bonusData.type]) then return 2 end
  831 +
  832 + local ticketId = csvdb["work_mainCsv"][bonusData.type].ticket
  833 + local workStar = role:getProperty("workStar")
  834 +
  835 + if bonusData.unlock ~= 0 and (not workStar[bonusData.unlock] or workStar[bonusData.unlock] == 0) then return 4 end
  836 + local workBattle = role:getProperty("workBattle")
  837 + workBattle[bonusData.type] = workBattle[bonusData.type] or 0
  838 + local needCount = count - (workBattle[bonusData.type] == 0 and 1 or 0)
  839 + if needCount ~= 0 and not role:checkItemEnough({[ticketId] = needCount}) then return 11 end
  840 +
  841 + if workStar[id] and workStar[id] >= (1 << #bonusData.sweep_condition:toTableArray(true)) - 1 then
  842 + if workBattle[bonusData.type] == 0 then
  843 + workBattle[bonusData.type] = 1
  844 + role:updateProperty({field = "workBattle", value = workBattle})
  845 + end
  846 + if needCount > 0 then
  847 + role:costItems({[ticketId] = needCount}, {log = {desc = "workBattle", int1 = id}})
  848 + end
  849 + redisproxy:hincrby(WORK_BATTLE_COUNT, role:getTimeResetRound(TimeReset["WorkBattle" .. bonusData.type]) * 10 + bonusData.type, count)
  850 + local reward, change = workWinReward(role, bonusData, 3, count, true)
  851 + SendPacket(actionCodes.Hang_startWorkBattleRpc, MsgPack.pack({reward = reward, change = change}))
  852 + else
  853 + local bTeam = role:getTeamFormatByType(TeamSystemType.BonusBattle)
  854 + if not next(bTeam) then return 5 end
  855 + role.__bonusBattleCache = {
  856 + key = tostring(math.random()),
  857 + id = id,
  858 + }
  859 + SendPacket(actionCodes.Hang_startWorkBattleRpc, MsgPack.pack({key = role.__bonusBattleCache.key}))
  860 + end
  861 +
  862 + return true
  863 +end
  864 +
  865 +function _M.endWorkBattleRpc(agent, data)
  866 + local role = agent.role
  867 + local msg = MsgPack.unpack(data)
  868 + local id = msg.id
  869 + local key = msg.key
  870 + local starNum = msg.starNum
  871 + if not role.__bonusBattleCache then return 1 end
  872 +
  873 +
  874 + if role.__bonusBattleCache.id ~= id or role.__bonusBattleCache.key ~= key then
  875 + SendPacket(actionCodes.Hang_endWorkBattleRpc, MsgPack.pack({errorCode = 1}))
  876 + return true
  877 + end
  878 + role.__bonusBattleCache = nil
  879 +
  880 + -- 防作弊
  881 + if not role:checkBattleCheat("work", {
  882 + id = id,
  883 + isWin = starNum and starNum > 0,
  884 + info = msg.info
  885 + }) then
  886 + SendPacket(actionCodes.Hang_endWorkBattleRpc, MsgPack.pack({errorCode = 1}))
  887 + return true
  888 + end
  889 +
  890 + local bonusData = csvdb["work_battleCsv"][id]
  891 + local ticketId = csvdb["work_mainCsv"][bonusData.type].ticket
  892 + local reward, change = {}
  893 +
  894 + local workStar = role:getProperty("workStar")
  895 + local oldStar = workStar[id] or 0
  896 + local curStar = 0
  897 + if starNum and starNum > 0 then
  898 + -- 胜利扣除次数
  899 +
  900 + local bTeam = role:getTeamFormatByType(TeamSystemType.BonusBattle)
  901 + local herosInfo = role:getTeamHerosInfo(bTeam).heros
  902 +
  903 + local check = {}
  904 + -- 1 通关
  905 + check[1] = function(_)
  906 + return true
  907 + end
  908 + -- 2 阵亡人数 <= N
  909 + check[2] = function(_, cond)
  910 + return msg.info.dead and msg.info.dead <= cond
  911 + end
  912 + -- 3 全员存活
  913 + check[3] = function(_)
  914 + return msg.info.dead and msg.info.dead == 0
  915 + end
  916 + -- 4 指定种族 >= N
  917 + check[4] = function(_, cond)
  918 + local count = 0
  919 + for _, one in pairs(herosInfo) do
  920 + local heroData = csvdb["unitCsv"][one.type]
  921 + if heroData.camp == cond then
  922 + count = count + 1
  923 + end
  924 + end
  925 + return count >= cond
  926 + end
  927 + -- 5 指定职业 >= N
  928 + check[5] = function(_, cond)
  929 + local count = 0
  930 + for _, one in pairs(herosInfo) do
  931 + local heroData = csvdb["unitCsv"][one.type]
  932 + if heroData.job == cond then
  933 + count = count + 1
  934 + end
  935 + end
  936 + return count >= cond
  937 + end
  938 + -- 6 含有指定角色
  939 + check[6] = function(_, cond)
  940 + for _, one in pairs(herosInfo) do
  941 + if one.type == cond then
  942 + return true
  943 + end
  944 + end
  945 + return false
  946 + end
  947 + -- 7 通关耗时 <= X 秒 msg.info.atime
  948 + check[7] = function(_, cond)
  949 + return msg.info.atime and msg.info.atime <= cond
  950 + end
  951 + curStar = 0
  952 + local sweepConds = bonusData.sweep_condition:toTableArray(true)
  953 + for i, cond in ipairs(sweepConds) do
  954 + if check[cond[1]] and check[cond[1]](table.unpack(cond)) then
  955 + curStar = curStar + (1 << (i - 1))
  956 + end
  957 + end
  958 + local status
  959 + local rewardType = 0
  960 + if curStar >= (1 << #sweepConds) - 1 then -- 满星
  961 + rewardType = 2
  962 + if oldStar == 0 then --通关
  963 + rewardType = 4
  964 + end
  965 + elseif oldStar == 0 then --通关
  966 + rewardType = 1
  967 + end
  968 +
  969 + if rewardType ~= 0 then
  970 + local workBattle = role:getProperty("workBattle")
  971 + workBattle[bonusData.type] = workBattle[bonusData.type] or 0
  972 + local needCount = 1 - (workBattle[bonusData.type] == 0 and 1 or 0)
  973 + if workBattle[1] == 0 then
  974 + workBattle[1] = 1
  975 + role:updateProperty({field = "workBattle", value = workBattle})
  976 + end
  977 + if needCount > 0 then
  978 + role:costItems({[ticketId] = needCount}, {log = {desc = "workBattle", int1 = id}})
  979 + end
  980 + redisproxy:hincrby(WORK_BATTLE_COUNT, role:getTimeResetRound(TimeReset["WorkBattle" .. bonusData.type]) * 10 + bonusData.type, 1)
  981 + reward, change = workWinReward(role, bonusData, rewardType)
  982 + end
  983 + else
  984 + curStar = oldStar
  985 + end
  986 + if curStar ~= oldStar then
  987 + workStar[id] = curStar
  988 + role:updateProperty({field = "workStar", value = workStar})
  989 + end
  990 +
  991 + role:checkBattle("work", {
  992 + id = id,
  993 + isWin = starNum and starNum > 0,
  994 + info = msg.info,
  995 + reward = reward,
  996 + })
  997 + role:mylog("hang_action", {desc = "workBattle", short1 = msg.starNum > 0 and 1 or 0, int1 = id})
  998 +
  999 + SendPacket(actionCodes.Hang_endWorkBattleRpc, MsgPack.pack({
  1000 + starNum = starNum,
  1001 + reward = reward,
  1002 + change = change
  1003 + }))
  1004 + return true
  1005 +end
  1006 +
753 1007 function _M.hangGiftRpc(agent, data)
754 1008 local role = agent.role
755 1009 local msg = MsgPack.unpack(data)
... ...
src/actions/RoleAction.lua
... ... @@ -161,6 +161,9 @@ function _M.loginRpc( agent, data )
161 161 role:getAdvData(true) -- 清掉不合格的数据
162 162 role:advEndlessSeasonCheck(true) -- 冒险赛季更新检查
163 163 role:checkSeaportTrade() -- 检查海港贸易季活动
  164 + if not next(role:getProperty("workBattle")) then
  165 + role:setProperty("workBattle", {round = math.floor((now - START_RESET_TIME) / 604800)})
  166 + end
164 167  
165 168 -- 跨天登陆事件
166 169 local resetMode = role:updateTimeReset(now)
... ... @@ -936,7 +939,15 @@ function _M.taskActiveRpc(agent, data)
936 939 return
937 940 end
938 941  
939   - local reward, change = role:award(taskData.reward, {log = {desc = "taskActive", int1 = taskType, int2 = taskId}})
  942 + local needReward = taskData.reward:toNumMap()
  943 + if taskData.reward_2 ~= 0 then
  944 + local day = weekday(skynet.timex())
  945 + local workMainCsv = csvdb["work_mainCsv"][day]
  946 + if workMainCsv then
  947 + needReward[workMainCsv.ticket] = taskData.reward_2
  948 + end
  949 + end
  950 + local reward, change = role:award(needReward, {log = {desc = "taskActive", int1 = taskType, int2 = taskId}})
940 951 role:changeUpdates({
941 952 { type = roleField[taskType], field = {"at", taskId}, value = -1 }
942 953 })
... ...
src/models/Role.lua
... ... @@ -119,6 +119,8 @@ Role.schema = {
119 119 towerTeams = {"table", {}}, -- 四个电波塔的队伍
120 120  
121 121 bonusStar = {"table", {}}, -- 奖励关卡 通关星星 {[id] = 1} 三个二进制位 表示三个星 从低到高 (1 << 0) (1 << 1) (1 << 2) 满星 (1 << 3) - 1
  122 + workStar = {"table", {}}, -- 夜间玩法 通关星星 {[id] = 1} 三个二进制位 表示三个星 从低到高 (1 << 0) (1 << 1) (1 << 2) 满星 (1 << 3) - 1
  123 + workBattle = {"table", {}}, -- 夜间玩法记录 {[1] = 1, [2] = 1, [3] = 1, [4] = 1, round = 10} -- 第N天打了多少次 round 轮次
122 124  
123 125 --引导相关
124 126 newerGuide = {"string","1=1"}, -- 新手引导 master=slave
... ... @@ -378,6 +380,8 @@ function Role:data()
378 380 towerTeams = self:getProperty("towerTeams"),
379 381  
380 382 bonusStar = self:getProperty("bonusStar"),
  383 + workStar = self:getProperty("workStar"),
  384 + workBattle = self:getProperty("workBattle"),
381 385  
382 386 newerGuide = self:getProperty("newerGuide"),
383 387 funcGuide = self:getProperty("funcGuide"),
... ...
src/models/RoleBattle.lua
... ... @@ -17,6 +17,7 @@ local BattleType = {
17 17 pvpc = 500,
18 18 pvph = 501,
19 19 act_battle = 502,
  20 + work = 301,
20 21 }
21 22  
22 23 RoleBattle.bind = function (Role)
... ... @@ -127,6 +128,18 @@ function Role:checkBattleCheat(battleType, params)
127 128 -- local carbonData = csvdb["bonus_battleCsv"][params.id]
128 129 -- enemyServer = packBattleEnemyCommon(carbonData)
129 130 end
  131 + cheat["work"] = function()
  132 + local team = self:getTeamBattleInfo(self:getTeamFormatByType(TeamSystemType.BonusBattle))
  133 + for slot, hero in pairs(team.heros) do
  134 + local temp = {}
  135 + for arr, _ in pairs(checkCheatAttrs) do
  136 + temp[arr] = hero[arr]
  137 + end
  138 + selfTeamServer[hero.type] = temp
  139 + end
  140 + -- local carbonData = csvdb["bonus_battleCsv"][params.id]
  141 + -- enemyServer = packBattleEnemyCommon(carbonData)
  142 + end
130 143 cheat["pvpc"] = function()
131 144 if not params.format then return end
132 145 local team = self:getTeamBattleInfo(params.format)
... ...
src/models/RoleLog.lua
... ... @@ -72,6 +72,8 @@ local ItemReason = {
72 72 towerBattle = 310, -- 电波塔战斗
73 73 advOver = 311, -- 冒险结算
74 74 advUnlock = 312, -- 拾荒解锁
  75 + workBattle = 313, -- workBattle夜间打工
  76 + workReward = 314, -- workBattle夜间打工 阶段奖励
75 77  
76 78 dinerFinishTask = 401, -- 餐厅完成任务
77 79 storybookReward = 402, -- 剧情奖励
... ...
src/models/RoleTimeReset.lua
... ... @@ -33,6 +33,38 @@ ResetFunc[&quot;CrossDay&quot;] = function(self, notify, response, now)
33 33 self:checkReturner()
34 34 end
35 35  
  36 + -- 检查 夜间打工
  37 + local workBattle = role:getProperty("workBattle")
  38 + local need = {}
  39 + for i = 1, 5 do
  40 + if workBattle[i] == 1 then
  41 + need[#need + 1] = workBattle.round * 10 + i
  42 + end
  43 + end
  44 + local change = false
  45 + if next(need) then
  46 + local ret = redisproxy:hmget(WORK_BATTLE_COUNT, table.unpack(need))
  47 + for idx, v in ipairs(need) do
  48 + local ctype = v % 10
  49 + local ccount = tonum(ret[idx])
  50 + local workMainCsv = csvdb["work_mainCsv"][ctype]
  51 + if ccount >= workMainCsv.target_num then
  52 + self:sendMail(workMainCsv.email, nil, workMainCsv.phase_award)
  53 + end
  54 + workBattle[ctype] = -1
  55 + end
  56 + change = true
  57 + end
  58 + local newRound = math.floor((now - START_RESET_TIME) / 604800)
  59 + if newRound ~= workBattle.round then
  60 + workBattle = {round = newRound}
  61 + change = true
  62 + end
  63 + if change then
  64 + self:setProperty("workBattle", workBattle)
  65 + response.workBattle = workBattle
  66 + end
  67 +
36 68 response.dTask = {}
37 69 response.advSup = self:getProperty("advSup")
38 70 self:log("onLogin")
... ...