| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859 |
- --------------------------------
- -- 文件名 : FootballMatchLogic.lua
- -- 文件说明 : 足球竞赛运营活动
- -- 配置表 : excel/ssecy/footballMatch.lua
- -- var[1]: costItem, winReward, loseReward
- -- task[id]: desc, reward
- -- reward[id]: desc, progressVal, reward
- -- gift[id]: buyId, limitCnt, reward
- --[[
- 玩法说明:
- 1. 每次开始消耗1个足球道具, 与人机对战5轮(每轮玩家射门+扑救各1次)
- 2. 射门/扑救方向: 1左 2中 3右; 人机非特殊轮次按1/3概率随机
- 3. 提前结束: 第3轮结束领先>=3、第4轮>=2、第5轮>=1
- 4. 第5轮玩家射门后防平局: 玩家领先1球则人机射向玩家扑救方向; 平局则人机不射向玩家扑救方向
- 5. 进行中退界面/断线, 重进后通过查询协议恢复进度
- DB: human.db.absAct[id] = {
- winCnt = 0, -- 累计胜场
- reward = {}, -- 仅记录已领取档位 [rewardId]=2
- task = {}, -- [taskId]=state(0未达成/1可领/2已领); 任务1/2每日重置, 任务3跨周重置
- gift = { [giftId] = buyCnt }, -- 礼包已购次数
- match = { -- 当前比赛(无比赛或已结束时 phase=0)
- opponentName = "",
- round = 1, -- 当前轮次 1-5
- phase = 1, -- 1待射门 2待扑救 0未开始/已结束
- playerScore = 0, -- 服务端内部用(提前结束/防平局判断), 不下发
- aiScore = 0,
- roundResults = { -- 5轮结果 player/ai: 0没进 1进球 2未出
- { player = 2, ai = 2 }, ...
- },
- },
- }
- 协议推送:
- CG_ABS_FOOTBALL_QUERY / START成功 / 分出胜负后 -> GC_ABS_FOOTBALL_QUERY
- CG_ABS_FOOTBALL_ACTION -> GC_ABS_FOOTBALL_ACTION; 分出胜负后再推 GC_ABS_FOOTBALL_QUERY
- 客户端请求(由 Handler.lua 调用):
- getAndSendMsg() -- CG_ABS_FOOTBALL_QUERY
- startMatch() -- CG_ABS_FOOTBALL_START
- playerAction() -- CG_ABS_FOOTBALL_ACTION
- queryTask() -- CG_ABS_FOOTBALL_TASK_QUERY
- getTaskReward() -- CG_ABS_FOOTBALL_TASK_GET
- queryReward() -- CG_ABS_FOOTBALL_REWARD_QUERY
- getReachReward() -- CG_ABS_FOOTBALL_REWARD_GET
- queryGift() -- CG_ABS_FOOTBALL_GIFT_QUERY
- 服务器模块接口:
- genAbsActData() -- 初始化活动DB
- isOpen() -- 活动是否开启
- isActive() -- 活动是否未开启(图标用)
- isRed() -- 红点
- onLogin() -- 登录补检任务
- updateDaily() -- 跨天重置任务1/2
- OnHuoYueReach100() -- 日/周活跃达标(由DailyTaskLogic/WeekTaskLogic触发)
- onCharge() -- 充值购买礼包回调
- GetRemainNum() -- 获取礼包剩余可购买次数(供其他模块调用)
- --]]
- --------------------------------
- local AbsActExcel = require("excel.absAct")
- local FootballExcel = require("excel.footballMatch")
- local AbsActLogic = require("absAct.AbsActLogic")
- local Msg = require("core.Msg")
- local Grid = require("bag.Grid")
- local BagLogic = require("bag.BagLogic")
- local Broadcast = require("broadcast.Broadcast")
- local Lang = require("common.Lang")
- local YunYingLogic = require("yunying.YunYingLogic")
- local BuyLogic = require("topup.BuyLogic")
- local CommonDefine = require("common.CommonDefine")
- local DataCache = require("core.DataCache")
- local RoleLogic = require("role.RoleLogic")
- local CreateRole = require("role.CreateRole")
- local LOGTAG = "football_match"
- local ACT_ID = 7701 -- 足球竞赛活动ID
- local VAR_INDEX = 1 -- footballMatch.var 配置索引
- -- 比赛阶段(DB)
- local PHASE_IDLE = 0 -- 未开始/已结束
- local PHASE_SHOOT = 1 -- 等待玩家射门
- local PHASE_SAVE = 2 -- 等待玩家扑救
- -- 协议 state
- local STATE_IDLE = 0
- local STATE_SHOOT = 1
- local STATE_SAVE = 2
- local STATE_ROUND_END = 3
- -- 玩家行动类型
- local ACTION_TYPE_SHOOT = 1
- local ACTION_TYPE_SAVE = 2
- -- 行动结果 ret
- local RET_NOT_END = 0
- local RET_PLAYER_WIN = 1
- local RET_PLAYER_LOSE = 2
- -- 单轮射门结果
- local RESULT_MISS = 0 -- 没进球
- local RESULT_GOAL = 1 -- 进球
- local RESULT_PENDING = 2 -- 还没有结果
- local MAX_ROUND = 5
- -- 射门/扑救方向: 1左 2中 3右
- local DIR_LEFT = 1
- local DIR_CENTER = 2
- local DIR_RIGHT = 3
- -- 提前结束胜差: 第3轮>=3, 第4轮>=2, 第5轮>=1
- local EARLY_WIN_GAP = {
- [3] = 3,
- [4] = 2,
- [5] = 1,
- }
- -- 任务ID: 1登录 2日活跃100 3周活跃100
- local TASK_ID_LOGIN = 1
- local TASK_ID_DAILY_HUOYUE = 2
- local TASK_ID_WEEK_HUOYUE = 3
- --------------------------------
- -- local 内部函数
- --------------------------------
- -- 获取玩法 var 配置
- local function getVarConfig()
- return (FootballExcel.var or {})[VAR_INDEX] or {}
- end
- -- 获取单场消耗道具 itemId, itemCnt
- local function getCostItemInfo()
- local costItem = getVarConfig().costItem or {}
- return costItem[1] or 0, costItem[2] or 0
- end
- -- 拷贝道具列表, 避免直接传配置表引用
- local function copyItemList(itemList)
- local items = {}
- for _, v in ipairs(itemList or {}) do
- items[#items + 1] = {v[1], v[2], v[3]}
- end
- return items
- end
- -- 初始化5轮比赛结果(默认未出结果)
- local function initMatchResults()
- local results = {}
- for i = 1, MAX_ROUND do
- results[i] = {player = RESULT_PENDING, ai = RESULT_PENDING}
- end
- return results
- end
- -- 获取活动DB, 不存在则初始化后返回
- local function getOrInitActData(human, id)
- if not human.db.absAct[id] then
- human.db.absAct[id] = genAbsActData(AbsActExcel.absActivity[id], human)
- end
- return human.db.absAct[id]
- end
- -- 随机射门/扑救方向(1-3)
- local function randomDirection()
- return math.random(DIR_LEFT, DIR_RIGHT)
- end
- -- 射门方向与扑救方向不同则进球
- local function isGoal(shootDir, saveDir)
- return shootDir ~= saveDir
- end
- -- 随机选取一名在线玩家名字作为对手名, 失败则用系统随机名
- local function getRandomOpponentName(myUuid)
- local playerUidList = DataCache.Get_PlayerUuidList()
- if not playerUidList or not next(playerUidList) then
- return CreateRole.getRandomName()
- end
- local candidates = {}
- local len = 0
- for uuid in pairs(playerUidList) do
- if uuid ~= myUuid then
- len = len + 1
- candidates[len] = uuid
- end
- end
- if len < 1 then
- return CreateRole.getRandomName()
- end
- for _ = 1, math.min(30, len) do
- local uuid = candidates[math.random(1, len)]
- local roleBase = {}
- RoleLogic.getRoleBaseByUuid(uuid, roleBase)
- if roleBase.name and roleBase.name ~= "" then
- return roleBase.name
- end
- end
- return CreateRole.getRandomName()
- end
- -- 计算人机射门方向; 第5轮防平局: 玩家领先1球则射向玩家扑救方向, 平局则不射向该方向
- local function calcAiShootDir(round, playerScore, aiScore, playerSaveDir)
- if round == MAX_ROUND then
- if playerScore - aiScore == 1 then
- return playerSaveDir
- elseif playerScore == aiScore then
- local dirs = {}
- for d = DIR_LEFT, DIR_RIGHT do
- if d ~= playerSaveDir then
- dirs[#dirs + 1] = d
- end
- end
- return dirs[math.random(1, #dirs)]
- end
- end
- return randomDirection()
- end
- -- 检查是否满足提前结束条件, 返回1玩家胜/2人机胜/nil继续
- local function checkEarlyWin(round, playerScore, aiScore)
- local gap = EARLY_WIN_GAP[round]
- if not gap then return end
- if playerScore - aiScore >= gap then
- return 1
- end
- if aiScore - playerScore >= gap then
- return 2
- end
- end
- -- 根据胜负获取本场奖励道具列表
- local function getMatchReward(isWin)
- local conf = getVarConfig()
- if isWin then
- return conf.winReward or {}
- end
- return conf.loseReward or {}
- end
- -- 获取任务状态
- local function getTaskState(absAct, taskId)
- return absAct.task and absAct.task[taskId]
- end
- -- 任务是否未达成(未记录或状态为0)
- local function isTaskPending(absAct, taskId)
- local state = getTaskState(absAct, taskId)
- return state == nil or state == CommonDefine.COMMON_PRIZE_STATE_NOGET
- end
- -- 刷新任务相关红点
- local function notifyTaskRed(human, id)
- YunYingLogic.sendBanner(human)
- local actConfig = AbsActExcel.absActivity[id]
- if actConfig then
- YunYingLogic.sendGroupUpdate(YYInfo[id], human, actConfig.panelID)
- end
- end
- -- 将任务标记为可领取并刷新红点
- local function tryCompleteTask(human, id, taskId)
- local absAct = human.db.absAct[id]
- if not absAct or not (FootballExcel.task or {})[taskId] then
- return
- end
- local state = getTaskState(absAct, taskId)
- if state == CommonDefine.COMMON_PRIZE_STATE_CANGET or state == CommonDefine.COMMON_PRIZE_STATE_GET then
- return
- end
- absAct.task[taskId] = CommonDefine.COMMON_PRIZE_STATE_CANGET
- notifyTaskRed(human, id)
- end
- -- 跨天重置任务1(登录)和任务2(日活跃)
- local function resetDailyTasks(absAct)
- absAct.task[TASK_ID_LOGIN] = CommonDefine.COMMON_PRIZE_STATE_NOGET
- absAct.task[TASK_ID_DAILY_HUOYUE] = CommonDefine.COMMON_PRIZE_STATE_NOGET
- end
- -- 跨周重置任务3(周活跃)
- local function checkWeekTaskReset(human, absAct)
- local WeekTaskLogic = require("dailyTask.WeekTaskLogic")
- if not WeekTaskLogic.isNeedWeekRefsh(human) then
- return
- end
- absAct.task[TASK_ID_WEEK_HUOYUE] = CommonDefine.COMMON_PRIZE_STATE_NOGET
- end
- -- 登录/查询时补检任务完成状态; 勿在 updateDaily 中调用, 此时 dailyTask 可能尚未清空
- local function tryInitTasks(human, id)
- local absAct = human.db.absAct[id]
- if not absAct then
- return
- end
- checkWeekTaskReset(human, absAct)
- if isTaskPending(absAct, TASK_ID_LOGIN) then
- tryCompleteTask(human, id, TASK_ID_LOGIN)
- end
- if isTaskPending(absAct, TASK_ID_DAILY_HUOYUE) then
- local DailyTaskLogic = require("dailyTask.DailyTaskLogic")
- if DailyTaskLogic.isReachMaxDailyHuoYue(human) then
- tryCompleteTask(human, id, TASK_ID_DAILY_HUOYUE)
- end
- end
- if isTaskPending(absAct, TASK_ID_WEEK_HUOYUE) then
- local WeekTaskLogic = require("dailyTask.WeekTaskLogic")
- if WeekTaskLogic.isReachMaxWeekHuoYue(human) then
- tryCompleteTask(human, id, TASK_ID_WEEK_HUOYUE)
- end
- end
- end
- -- 获取累计胜场档位奖励状态
- local function getReachRewardState(absAct, rewardId, progressVal)
- if absAct.reward[rewardId] == CommonDefine.COMMON_PRIZE_STATE_GET then
- return CommonDefine.COMMON_PRIZE_STATE_GET
- end
- if absAct.winCnt >= progressVal then
- return CommonDefine.COMMON_PRIZE_STATE_CANGET
- end
- return CommonDefine.COMMON_PRIZE_STATE_NOGET
- end
- -- 结束比赛: 更新胜场、发放奖励、重置比赛状态
- local function finishMatch(human, id, match, winner)
- local absAct = getOrInitActData(human, id)
- local isWin = winner == 1
- if isWin then
- absAct.winCnt = absAct.winCnt + 1
- end
- BagLogic.addItemList(human, copyItemList(getMatchReward(isWin)), LOGTAG)
- match.phase = PHASE_IDLE
- YunYingLogic.sendBanner(human)
- local config = AbsActExcel.absActivity[id]
- if config then
- YunYingLogic.sendGroupUpdate(YYInfo[id], human, config.panelID)
- end
- end
- -- 填充单轮比赛结果到协议结构
- local function fillRoundResultNet(net, roundData)
- net.player = roundData.player or RESULT_PENDING
- net.ai = roundData.ai or RESULT_PENDING
- end
- -- 填充5轮比赛结果
- local function fillAllRoundResults(msgRet, match)
- for i = 1, MAX_ROUND do
- local roundData = match and match.roundResults and match.roundResults[i]
- if not roundData then
- roundData = {player = RESULT_PENDING, ai = RESULT_PENDING}
- end
- fillRoundResultNet(msgRet.roundResults[i], roundData)
- end
- msgRet.roundResults[0] = MAX_ROUND
- end
- -- DB phase 转查询协议 state
- local function phaseToQueryState(phase)
- if phase == PHASE_SHOOT then
- return STATE_SHOOT
- end
- if phase == PHASE_SAVE then
- return STATE_SAVE
- end
- return STATE_IDLE
- end
- -- 任务分页是否有红点
- local function hasTaskPageRedDot(absAct)
- for taskId in pairs(FootballExcel.task or {}) do
- if getTaskState(absAct, taskId) == CommonDefine.COMMON_PRIZE_STATE_CANGET then
- return true
- end
- end
- return false
- end
- -- 奖励分页是否有红点
- local function hasRewardPageRedDot(absAct)
- for index, v in pairs(FootballExcel.reward or {}) do
- if getReachRewardState(absAct, index, v.progressVal) == CommonDefine.COMMON_PRIZE_STATE_CANGET then
- return true
- end
- end
- return false
- end
- -- 填充分页红点
- local function fillPageRedDotArr(msgRet, absAct)
- msgRet.pageRedDotArr[0] = 2
- msgRet.pageRedDotArr[1] = hasTaskPageRedDot(absAct) and 1 or 0
- msgRet.pageRedDotArr[2] = hasRewardPageRedDot(absAct) and 1 or 0
- end
- -- 填充单场消耗道具
- local function fillCostItem(msgRet)
- local itemId, itemCnt = getCostItemInfo()
- Grid.makeItem(msgRet.costItem, itemId, itemCnt)
- end
- -- 填充 GC_ABS_FOOTBALL_QUERY
- local function fillQueryNet(msgRet, human, id)
- local absAct = getOrInitActData(human, id)
- local match = absAct.match
- msgRet.playerName = human.db.name or ""
- msgRet.winCnt = absAct.winCnt
- fillPageRedDotArr(msgRet, absAct)
- fillCostItem(msgRet)
- if not match or match.phase == PHASE_IDLE then
- msgRet.opponentName = ""
- msgRet.round = 0
- msgRet.state = STATE_IDLE
- fillAllRoundResults(msgRet, match)
- return
- end
- msgRet.opponentName = match.opponentName or ""
- msgRet.round = match.round or 1
- msgRet.state = phaseToQueryState(match.phase)
- fillAllRoundResults(msgRet, match)
- end
- -- 填充 GC_ABS_FOOTBALL_ACTION
- local function fillActionNet(msgRet, match, extra)
- msgRet.ret = extra.ret or RET_NOT_END
- msgRet.actionType = extra.actionType or 0
- msgRet.playerDir = extra.playerDir or 0
- msgRet.opponentDir = extra.opponentDir or 0
- msgRet.isGoal = extra.isGoal or 0
- msgRet.round = extra.round or 0
- msgRet.state = extra.state or STATE_IDLE
- fillAllRoundResults(msgRet, match)
- end
- -- 下发比赛查询协议 GC_ABS_FOOTBALL_QUERY
- local function sendQuery(human, id)
- local msgRet = Msg.gc.GC_ABS_FOOTBALL_QUERY
- fillQueryNet(msgRet, human, id)
- Msg.send(msgRet, human.fd)
- end
- -- 下发行动结果 GC_ABS_FOOTBALL_ACTION
- local function sendActionResult(human, match, extra)
- local msgRet = Msg.gc.GC_ABS_FOOTBALL_ACTION
- fillActionNet(msgRet, match, extra)
- Msg.send(msgRet, human.fd)
- end
- -- 填充道具列表到协议结构
- local function fillItemList(netList, itemList)
- local len = #itemList
- for i = 1, len do
- Grid.makeItem(netList[i], itemList[i][1], itemList[i][2])
- end
- netList[0] = len
- end
- -- 检查活动是否开启, 未开启则下发错误
- local function checkActStarted(human, id)
- if AbsActLogic.isStarted(human, id) then
- return true
- end
- Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
- return false
- end
- --------------------------------
- -- 服务器模块接口
- --------------------------------
- -- 初始化活动DB
- function genAbsActData(config, human)
- return {
- winCnt = 0,
- reward = {},
- task = {},
- gift = {},
- }
- end
- -- 活动是否开启
- function isOpen(human, YYInfo, funcConfig)
- local state, endTime, startTime = AbsActLogic.isStarted(human, funcConfig.funcID)
- if not state then return end
- return true, endTime, startTime
- end
- -- 活动是否未开启(运营图标置灰用)
- function isActive(human, YYInfo, funcConfig)
- return not isOpen(human, YYInfo, funcConfig)
- end
- -- 红点: 有可领奖励/任务(有道具可开赛不再显示红点, 逻辑暂屏蔽)
- function isRed(human, YYInfo, funcConfig)
- local id = funcConfig.funcID
- local state = AbsActLogic.isStarted(human, id)
- if not state then return end
- local absAct = human.db.absAct[id]
- if not absAct then return end
- if hasRewardPageRedDot(absAct) or hasTaskPageRedDot(absAct) then
- return true
- end
- --[[ 有足球道具且当前无进行中比赛时显示红点, 暂不需要
- local itemId, itemCnt = getCostItemInfo()
- if itemId > 0 and itemCnt > 0 and (not absAct.match or absAct.match.phase == PHASE_IDLE) then
- if BagLogic.getItemCnt(human, itemId) >= itemCnt then
- return true
- end
- end
- --]]
- return false
- end
- -- 登录时补检任务状态
- function onLogin(human, funcID)
- local state = AbsActLogic.isStarted(human, funcID)
- if not state then
- return
- end
- getOrInitActData(human, funcID)
- tryInitTasks(human, funcID)
- end
- -- 跨天回调: 重置日任务并补检登录任务
- function updateDaily(human, funcID)
- local state = AbsActLogic.isStarted(human, funcID)
- if not state then
- return
- end
- local absAct = human.db.absAct[funcID]
- if not absAct then
- return
- end
- resetDailyTasks(absAct)
- checkWeekTaskReset(human, absAct)
- tryCompleteTask(human, funcID, TASK_ID_LOGIN)
- end
- -- 日/周活跃达100时触发(由 DailyTaskLogic/WeekTaskLogic 调用)
- function OnHuoYueReach100(human)
- if not AbsActLogic.isStarted(human, ACT_ID) then
- return
- end
- getOrInitActData(human, ACT_ID)
- local DailyTaskLogic = require("dailyTask.DailyTaskLogic")
- if DailyTaskLogic.isReachMaxDailyHuoYue(human) then
- tryCompleteTask(human, ACT_ID, TASK_ID_DAILY_HUOYUE)
- end
- local WeekTaskLogic = require("dailyTask.WeekTaskLogic")
- if WeekTaskLogic.isReachMaxWeekHuoYue(human) then
- tryCompleteTask(human, ACT_ID, TASK_ID_WEEK_HUOYUE)
- end
- end
- -- 充值购买礼包回调
- function onCharge(human, price, funcID, buyID, buyNum)
- local state = AbsActLogic.isStarted(human, funcID)
- if not state then return end
- local absAct = getOrInitActData(human, funcID)
- buyNum = buyNum or 1
- for index, v in pairs(FootballExcel.gift or {}) do
- if v.buyId == buyID then
- absAct.gift = absAct.gift or {}
- local nowCnt = absAct.gift[index] or 0
- if nowCnt + buyNum > (v.limitCnt or 0) then
- return
- end
- absAct.gift[index] = nowCnt + buyNum
- local items = copyItemList(v.reward)
- for _, item in ipairs(items) do
- item[2] = item[2] * buyNum
- end
- BagLogic.addItemList(human, items, LOGTAG)
- queryGift(human, funcID)
- YunYingLogic.sendBanner(human)
- return
- end
- end
- end
- -- 获取礼包剩余可购买次数(供 BuyLogic 等模块调用)
- function GetRemainNum(human, buyId)
- if not AbsActLogic.isStarted(human, ACT_ID) then
- return 0
- end
- for index, v in pairs(FootballExcel.gift or {}) do
- if v.buyId == buyId then
- local maxCnt = v.limitCnt or 0
- local absAct = human.db.absAct[ACT_ID]
- if not absAct then
- return maxCnt
- end
- local nowCnt = absAct.gift and absAct.gift[index] or 0
- return nowCnt >= maxCnt and 0 or (maxCnt - nowCnt)
- end
- end
- return 0
- end
- --------------------------------
- -- 客户端请求处理
- --------------------------------
- -- CG_ABS_FOOTBALL_QUERY 查询比赛进度(断线重进恢复用)
- function getAndSendMsg(human, id)
- if not checkActStarted(human, id) then return end
- getOrInitActData(human, id)
- sendQuery(human, id)
- end
- -- CG_ABS_FOOTBALL_START 开始比赛, 消耗1个足球道具
- function startMatch(human, id)
- if not checkActStarted(human, id) then return end
- local absAct = getOrInitActData(human, id)
- if absAct.match and absAct.match.phase ~= PHASE_IDLE then
- return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
- end
- local itemId, itemCnt = getCostItemInfo()
- if itemId <= 0 or itemCnt <= 0 or BagLogic.getItemCnt(human, itemId) < itemCnt then
- return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
- end
- BagLogic.delItem(human, itemId, itemCnt, LOGTAG)
- absAct.match = {
- opponentName = getRandomOpponentName(human.db._id),
- round = 1,
- phase = PHASE_SHOOT,
- playerScore = 0,
- aiScore = 0,
- roundResults = initMatchResults(),
- }
- sendQuery(human, id)
- end
- -- 玩家射门
- local function playerShoot(human, id, shootDir)
- local absAct = getOrInitActData(human, id)
- local match = absAct.match
- if not match or match.phase ~= PHASE_SHOOT then
- return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
- end
- local round = match.round
- local aiSaveDir = randomDirection()
- local goal = isGoal(shootDir, aiSaveDir)
- if goal then
- match.playerScore = match.playerScore + 1
- match.roundResults[round].player = RESULT_GOAL
- else
- match.roundResults[round].player = RESULT_MISS
- end
- match.phase = PHASE_SAVE
- sendActionResult(human, match, {
- ret = RET_NOT_END,
- actionType = ACTION_TYPE_SHOOT,
- playerDir = shootDir,
- opponentDir = aiSaveDir,
- isGoal = goal and 1 or 0,
- round = round,
- state = STATE_SAVE,
- })
- end
- -- 玩家扑救; 每轮结束检查提前结束或进入下一轮
- local function playerSave(human, id, saveDir)
- local absAct = getOrInitActData(human, id)
- local match = absAct.match
- if not match or match.phase ~= PHASE_SAVE then
- return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
- end
- local round = match.round
- local aiShootDir = calcAiShootDir(round, match.playerScore, match.aiScore, saveDir)
- local goal = isGoal(aiShootDir, saveDir)
- if goal then
- match.aiScore = match.aiScore + 1
- match.roundResults[round].ai = RESULT_GOAL
- else
- match.roundResults[round].ai = RESULT_MISS
- end
- local winner = checkEarlyWin(round, match.playerScore, match.aiScore)
- if not winner and round >= MAX_ROUND then
- if match.playerScore > match.aiScore then
- winner = 1
- elseif match.aiScore > match.playerScore then
- winner = 2
- else
- winner = 1
- end
- end
- if winner then
- finishMatch(human, id, match, winner)
- sendActionResult(human, match, {
- ret = winner == 1 and RET_PLAYER_WIN or RET_PLAYER_LOSE,
- actionType = ACTION_TYPE_SAVE,
- playerDir = saveDir,
- opponentDir = aiShootDir,
- isGoal = goal and 1 or 0,
- round = round,
- state = STATE_ROUND_END,
- })
- sendQuery(human, id)
- return
- end
- match.round = round + 1
- match.phase = PHASE_SHOOT
- sendActionResult(human, match, {
- ret = RET_NOT_END,
- actionType = ACTION_TYPE_SAVE,
- playerDir = saveDir,
- opponentDir = aiShootDir,
- isGoal = goal and 1 or 0,
- round = round,
- state = STATE_ROUND_END,
- })
- end
- -- CG_ABS_FOOTBALL_ACTION 玩家行动(射门/扑救)
- function playerAction(human, id, actionType, dir)
- if not checkActStarted(human, id) then return end
- if dir < DIR_LEFT or dir > DIR_RIGHT then
- return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
- end
- if actionType == ACTION_TYPE_SHOOT then
- playerShoot(human, id, dir)
- elseif actionType == ACTION_TYPE_SAVE then
- playerSave(human, id, dir)
- else
- return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
- end
- end
- -- CG_ABS_FOOTBALL_TASK_QUERY 查询任务列表
- function queryTask(human, id)
- if not checkActStarted(human, id) then return end
- local absAct = getOrInitActData(human, id)
- tryInitTasks(human, id)
- local msgRet = Msg.gc.GC_ABS_FOOTBALL_TASK_QUERY
- local len = 0
- for index, v in pairs(FootballExcel.task or {}) do
- len = len + 1
- local net = msgRet.list[len]
- local taskState = getTaskState(absAct, index) or CommonDefine.COMMON_PRIZE_STATE_NOGET
- net.id = index
- net.desc = v.desc or ""
- net.needCnt = 1
- net.nowCnt = taskState >= CommonDefine.COMMON_PRIZE_STATE_CANGET and 1 or 0
- net.state = taskState
- fillItemList(net.item, v.reward or {})
- end
- msgRet.list[0] = len
- Msg.send(msgRet, human.fd)
- end
- -- CG_ABS_FOOTBALL_TASK_GET 领取任务奖励
- function getTaskReward(human, id, taskId)
- if not checkActStarted(human, id) then return end
- local config = (FootballExcel.task or {})[taskId]
- if not config then
- return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
- end
- local absAct = getOrInitActData(human, id)
- local taskState = getTaskState(absAct, taskId)
- if taskState == CommonDefine.COMMON_PRIZE_STATE_GET then
- return Broadcast.sendErr(human, Lang.YUNYING_GET_ERR_HADGET)
- end
- if taskState ~= CommonDefine.COMMON_PRIZE_STATE_CANGET then
- return Broadcast.sendErr(human, Lang.YUNYING_GET_ERR_CONDITION)
- end
- absAct.task[taskId] = CommonDefine.COMMON_PRIZE_STATE_GET
- BagLogic.addItemList(human, copyItemList(config.reward), LOGTAG)
- queryTask(human, id)
- YunYingLogic.sendBanner(human)
- end
- -- CG_ABS_FOOTBALL_REWARD_QUERY 查询累计胜场奖励
- function queryReward(human, id)
- if not checkActStarted(human, id) then return end
- local absAct = getOrInitActData(human, id)
- local msgRet = Msg.gc.GC_ABS_FOOTBALL_REWARD_QUERY
- msgRet.winCnt = absAct.winCnt
- local len = 0
- for index, v in pairs(FootballExcel.reward or {}) do
- len = len + 1
- local net = msgRet.list[len]
- net.id = index
- net.desc = v.desc or ""
- net.needCnt = v.progressVal or 0
- net.nowCnt = absAct.winCnt
- net.state = getReachRewardState(absAct, index, v.progressVal)
- fillItemList(net.item, v.reward or {})
- end
- msgRet.list[0] = len
- Msg.send(msgRet, human.fd)
- end
- -- CG_ABS_FOOTBALL_REWARD_GET 领取累计胜场奖励
- function getReachReward(human, id, rewardId)
- if not checkActStarted(human, id) then return end
- local config = (FootballExcel.reward or {})[rewardId]
- if not config then
- return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
- end
- local absAct = getOrInitActData(human, id)
- local rewardState = getReachRewardState(absAct, rewardId, config.progressVal)
- if rewardState == CommonDefine.COMMON_PRIZE_STATE_GET then
- return Broadcast.sendErr(human, Lang.YUNYING_GET_ERR_HADGET)
- end
- if rewardState ~= CommonDefine.COMMON_PRIZE_STATE_CANGET then
- return Broadcast.sendErr(human, Lang.YUNYING_GET_ERR_CONDITION)
- end
- absAct.reward[rewardId] = CommonDefine.COMMON_PRIZE_STATE_GET
- BagLogic.addItemList(human, copyItemList(config.reward), LOGTAG)
- queryReward(human, id)
- YunYingLogic.sendBanner(human)
- end
- -- CG_ABS_FOOTBALL_GIFT_QUERY 查询礼包列表
- function queryGift(human, id)
- if not checkActStarted(human, id) then return end
- local absAct = getOrInitActData(human, id)
- local msgRet = Msg.gc.GC_ABS_FOOTBALL_GIFT_QUERY
- local len = 0
- for index, v in pairs(FootballExcel.gift or {}) do
- len = len + 1
- local net = msgRet.list[len]
- net.id = index
- net.maxCnt = v.limitCnt or 0
- net.nowCnt = absAct.gift and absAct.gift[index] or 0
- fillItemList(net.item, v.reward or {})
- net.buyMsg[0] = 0
- if v.buyId and v.buyId > 0 then
- BuyLogic.fontBuyItem(human, net.buyMsg[1], v.buyId)
- net.buyMsg[0] = 1
- end
- end
- msgRet.list[0] = len
- Msg.send(msgRet, human.fd)
- end
|