1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153 |
- -- 罗兰峡谷攻城战
- RolandSeige = {}
- local this = {}
- -- -----------------------------------------------玩家积分类-----------------------------------------------------
- -- 副本玩家积分类
- local RoleScoreDTO = {}
- RoleScoreDTO.__index = RoleScoreDTO
- -- 副本玩家积分对象
- function RoleScoreDTO.new(rid, unionId)
- local instance = setmetatable({}, RoleScoreDTO)
- instance.id = rid
- instance.unionId = unionId
- instance.attackBuilding = 0 -- 攻方攻击建筑的次数
- instance.kill = 0 -- 击杀玩家的次数
- instance.hurt = 0 -- 伤害量
- instance.occupy = 0 -- 攻方占领次数
- instance.stay = 0 -- 守方停留圈内时间(秒)
- return instance
- end
- -- 计算玩家个人积分
- function RoleScoreDTO.calTotalScore(roleScoreDTO)
- local attackScore = tonumber(ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.ATTACK_BUILDING_SCORE))
- local killScore = tonumber(ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.KILL_SCORE))
- local hurtScore = tonumber(ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.HURT_SCORE))
- local occupyScore = tonumber(ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.OCCUPY_SCORE))
- local stayScore = tonumber(ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.STAY_SCORE))
- local totalScore = roleScoreDTO.attackBuilding * attackScore
- + roleScoreDTO.kill * killScore
- + math.floor(roleScoreDTO.hurt / hurtScore)
- + roleScoreDTO.occupy * occupyScore
- + math.floor(roleScoreDTO.stay / stayScore)
- return totalScore
- end
- function RoleScoreDTO.calTotalScoreByActor(actor, mapId)
- local roleScoreDTO = RoleScoreDTO.get(actor, mapId)
- return RoleScoreDTO.calTotalScore(roleScoreDTO)
- end
- function RoleScoreDTO.get(actor, mapId)
- return getenvirvar(mapId, DuplicateVarConst.ROLAND_SEIGE.PLAYER_KEY_PREFIX .. actor:toString())
- end
- function RoleScoreDTO.set(actor, mapId, roleScoreDTO)
- setenvirvar(mapId, DuplicateVarConst.ROLAND_SEIGE.PLAYER_KEY_PREFIX .. actor:toString(), roleScoreDTO)
- end
- function RoleScoreDTO.addAttackBuilding(actor, mapId, times)
- local roleScoreDTO = RoleScoreDTO.get(actor, mapId)
- roleScoreDTO.attackBuilding = roleScoreDTO.attackBuilding + times
- RoleScoreDTO.set(actor, mapId, roleScoreDTO)
- end
- function RoleScoreDTO.addKill(actor, mapId, times)
- local roleScoreDTO = RoleScoreDTO.get(actor, mapId)
- roleScoreDTO.kill = roleScoreDTO.kill + times
- RoleScoreDTO.set(actor, mapId, roleScoreDTO)
- end
- function RoleScoreDTO.addHurt(actor, mapId, times)
- local roleScoreDTO = RoleScoreDTO.get(actor, mapId)
- roleScoreDTO.hurt = roleScoreDTO.hurt + times
- RoleScoreDTO.set(actor, mapId, roleScoreDTO)
- end
- function RoleScoreDTO.addOccuoy(actor, mapId, times)
- local roleScoreDTO = RoleScoreDTO.get(actor, mapId)
- roleScoreDTO.occupy = roleScoreDTO.occupy + times
- RoleScoreDTO.set(actor, mapId, roleScoreDTO)
- end
- function RoleScoreDTO.addStay(actor, mapId, times)
- local roleScoreDTO = RoleScoreDTO.get(actor, mapId)
- roleScoreDTO.stay = roleScoreDTO.stay + times
- RoleScoreDTO.set(actor, mapId, roleScoreDTO)
- end
- -- ---------------------------------------------------------------------------------------------------------------------------------------
- -- ----------------------------------------------- 战盟进度条类 -----------------------------------------------------
- local UnionProgressDTO = {}
- UnionProgressDTO.__index = UnionProgressDTO
- function UnionProgressDTO.new(unionId, isMax)
- local instance = setmetatable({}, RoleScoreDTO)
- local needTime = tonumber(ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.OCCUPY_PROGRESS_TIME))
- instance.max = needTime
- if isMax then
- instance.now = needTime
- else
- instance.now = 0
- end
- instance.unionId = unionId
- local unionInfo = getunioninfo(unionId)
- instance.unionName = unionInfo.unionname
- return instance
- end
- function UnionProgressDTO.get(mapId, unionId)
- return getenvirvar(mapId, DuplicateVarConst.ROLAND_SEIGE.UNION_SCORE_PREFIX .. tostring(unionId))
- end
- function UnionProgressDTO.set(mapId, unionId, occupyDTO)
- setenvirvar(mapId, DuplicateVarConst.ROLAND_SEIGE.UNION_SCORE_PREFIX .. tostring(unionId), occupyDTO)
- end
- function UnionProgressDTO.add(mapId, unionId, add)
- local occupyDTO = UnionProgressDTO.get(mapId, unionId)
- local old = occupyDTO.now
- local new = old + add
- if new > occupyDTO.max then
- new = occupyDTO.max
- end
- occupyDTO.now = new
- UnionProgressDTO.set(mapId, unionId, occupyDTO)
- return occupyDTO
- end
- function UnionProgressDTO.reset(mapId, unionId)
- local occupyDTO = UnionProgressDTO.get(mapId, unionId)
- occupyDTO.now = 0
- UnionProgressDTO.set(mapId, unionId, occupyDTO)
- return occupyDTO
- end
- function UnionProgressDTO.isMax(progressDTO)
- if progressDTO.now >= progressDTO.max then
- return true
- end
- return false
- end
- -- ---------------------------------------------------------------------------------------------------------------------------------------
- -- ----------------------------------------------- 战盟进度条类 -----------------------------------------------------
- local LogRecord = {}
- function LogRecord.new()
- local log = {}
- log.winUninId = 0
- log.winType = "" -- 占领 或 积分
- log.leader = 0
- log.personalScoreList = {}
- return log
- end
- function LogRecord.log(log)
- local content = "本次罗兰峡谷攻城战获胜方战盟ID:" .. log.winUninId .. "(为0表示攻城失败) ;占领类型为:" .. log.winType .. " ;占领战盟盟主为:" .. log.leader .. " ;"
- local personalScoreContent = "个人积分如下:"
- for rid, score in pairs(log.personalScoreList) do
- personalScoreContent = personalScoreContent .. "{" .. rid .. "积分为:" .. score .. " };"
- end
- content = content .. personalScoreContent
- info(content)
- logop(LogOpType.ROLAND_SEIGE, content)
- end
- -- ---------------------------------------------------------------------------------------------------------------------------------------
- ---------------------------------------------------------- 请求 -----------------------------------------------------------------
- -- 请求主面板信息
- function RolandSeige.ReqMainPanel(actor)
- local res = {}
- -- 上次占领战盟信息
- local unionId = this.GetLastOccupyUnionId()
- if unionId ~= nil and unionId > 0 then
- local union = {}
- local unionInfo = getunioninfo(actor, unionId)
- union.id = unionId
- union.name = unionInfo.unionname
- -- 盟主和副盟主
- union.leader = unionInfo.leaderid
- local memberList = unionInfo.memberinfos
- local fuLeaders = {}
- for _, memberInfo in pairs(memberList) do
- if memberInfo.position == 2 then
- table.insert(fuLeaders, memberInfo.rid)
- if #fuLeaders >= 2 then
- break
- end
- end
- end
- union.deputys = fuLeaders
- res.union = union
- end
- -- 活动开启情况,未开启发送下次开启时间戳,区分首次开启
- local openTimeSec = math.ceil(getbaseinfo(actor, "serveropentime") / 1000)
- local day, hour, minute = this.GetFirstOpenTime()
- local firstOpenSec = openTimeSec + (day - 1) * 86400 + hour * 3600 + minute * 60
- local nowSec = getbaseinfo("nowsec")
- if nowSec <= firstOpenSec then
- res.open = false
- res.nextTime = firstOpenSec
- else
- local activityInfo = getactivityinfo(DuplicateType.ROLAND_SEIGE)
- if activityInfo.open then
- res.open = true
- else
- res.nextTime = math.ceil(activityInfo.nextopentime / 1000)
- res.open = false
- end
- end
- sendluamsg(actor, LuaMessageIdToClient.RES_ROLAND_SEIGE_MAIN_PANEL, res)
- end
- -- 创建攻城战副本
- function RolandSeige.OpenDuplicate(system)
- if not RolandSeige.CanOpenActivity() then
- info("定时器开启罗兰攻城战,未达到首次开启要求,直接关闭此活动")
- closeactivity(DuplicateType.ROLAND_SEIGE)
- return
- end
- local oldDupId = this.GetCurrentDupId()
- if oldDupId ~= nil and oldDupId ~= 0 then
- gameDebug.assertPrintTrace(false, "罗兰峡谷攻城战副本已创建,重复创建副本!")
- return
- end
- -- 创建全服唯一的副本并储存全局变量
- local repId = tonumber(ConfigDataManager.getTableValue("cfg_rep", "id", "type", DuplicateType.ROLAND_SEIGE))
- local dupId = DuplicateCommon.CreateDupMapCommon(system, repId, true)
- this.SetCurrentDupId(dupId)
- end
- -- 请求进入攻城战副本
- function RolandSeige.ReqEnterDupLicate(actor)
- -- 副本需要开启中
- local dupId = this.GetCurrentDupId()
- if dupId == nil or dupId == 0 then
- gameDebug.assertPrintTrace(false, actor:toString() .. "请求进入罗兰峡谷攻城战,副本未开启或已关闭!")
- return
- end
- -- 通用检查
- local repId = tonumber(ConfigDataManager.getTableValue("cfg_rep", "id", "type", DuplicateType.ROLAND_SEIGE))
- local commonCheck = DuplicateCommon.CheckEnterConditonCommon(actor, repId)
- if commonCheck ~= EnterLimitResultConst.ALLOW then
- gameDebug.assertPrintTrace(false, actor:toString() .. "请求进入罗兰峡谷攻城战,进入失败!条件不满足:" .. commonCheck)
- return
- end
- --玩家必须加入战盟
- local unionId = getbaseinfo(actor, "guildid")
- if unionId == 0 then
- gameDebug.assertPrintTrace(false, actor:toString() .. "请求进入罗兰峡谷攻城战,未处于一个战盟中!")
- return
- end
- -- 盟主需要在攻城战副本中,4.3版本移除
- local unionInfo = getunioninfo(actor)
- local leaderId = unionInfo.leaderid
- -- if tostring(leaderId) ~= actor:toString() then
- -- local leaderActor = getactor(leaderId)
- -- local leaderMapId = getbaseinfo(leaderActor, "unimapid")
- -- if dupId ~= leaderMapId then
- -- tipinfo(actor, "条件不满足!")
- -- return
- -- end
- -- end
- -- 战盟人数要求
- local needSize = tonumber(ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.NEED_UNION_SIZE))
- local unionSize = unionInfo.num
- if unionSize < needSize then
- tipinfo(actor, "条件不满足!")
- info(actor:toString() .. "请求进入罗兰峡谷攻城战,战盟人数不足!当前人数:" .. unionSize .. " ;需要人数:" .. needSize)
- return
- end
- --回蓝回血
- DuplicateCommon.RecoverHPMP(actor)
- -- 进入副本
- local transferPointStr = ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.TRANSFER_POINT)
- local transferPointStrSplit = string.split(transferPointStr, "|")
- local selfCamp = this.GetCamp(actor, dupId)
- local transferStr
- if selfCamp == RolandConst.CAMP_TYPE.ATTACK then
- transferStr = transferPointStrSplit[1]
- else
- transferStr = transferPointStrSplit[2]
- end
- local transferStrSplit = string.split(transferStr, "#")
- local x = transferStrSplit[1]
- local y = transferStrSplit[2]
- enterduplicate(actor, dupId, x, y)
- end
- -- 玩家是否在罗兰峡谷
- function RolandSeige.IsPlayerInRoland(actor)
- local mapId = getbaseinfo(actor, "unimapid")
- local dupInfo = getduplicate(mapId)
- if dupInfo == nil then
- return false
- end
- if dupInfo.type ~= DuplicateType.ROLAND_SEIGE then
- return false
- end
- return true
- end
- function RolandSeige.CanAttackRolandWall(actor, targetActor, castType, targetType)
- if RolandSeige.IsPlayerInRoland(actor) then
- if targetType == MapObjectType.MONSTER then
- local mapId = getbaseinfo(actor, "unimapid")
- if castType == MapObjectType.PET or castType == MapObjectType.PARTNER then
- local masterId = getbaseinfo(actor, "master")
- actor = getactor(masterId, mapId)
- end
- local camp = this.GetCamp(actor, mapId)
- if camp == RolandConst.CAMP_TYPE.DEFEND then
- return false
- end
- end
- end
- return true
- end
- -----------------------------------------------------------------------------------------------------------------------------------------
- ---------------------------------------------------------- 事件 -----------------------------------------------------------------
- -- 服务器分钟心跳,用于首次开启活动
- function RolandSeige.ServerMinuteHeart()
- local seconds = getbaseinfo("nowsec")
- local now = TimeUtil.timeToDate(seconds)
- local nowMin = now.min
- local nowHour = now.hour
- local day, hour, minute = this.GetFirstOpenTime()
- if nowHour == hour and nowMin == minute then
- local openDays = getbaseinfo("serveropendays")
- if day == openDays then
- -- 活动是否开启
- local activityInfo = getactivityinfo(DuplicateType.ROLAND_SEIGE)
- if activityInfo ~= nil then
- local isOpen = activityInfo.open
- if isOpen then
- gameDebug.assertPrintTrace(false, "首次开启罗兰攻城战时活动已被开启")
- return
- end
- end
- -- 开启活动
- openactivity(DuplicateType.ROLAND_SEIGE)
- end
- end
- end
- -- @description 副本阶段更新
- -- @param 系统id;地图唯一id;副本类型;副本阶段(1-准备 2-战斗 3-结算);下一阶段开始时间戳;配置id(cfg_rep的id)
- function RolandSeige.DupStateUpdate(system, mapId, state, nextStateStartTime, configId)
- if state == DuplicateState.PREPARE then
- this.InitRolandData(mapId, configId)
- --刷怪
- local monsterId = ConfigDataManager.getTableValue("cfg_rep", "monster", "id", configId)
- local monsterList = DuplicateCommon.DupGenMonsterCommon(mapId, monsterId)
- for _, monActor in pairs(monsterList) do
- -- 设置怪物的朝向
- setmapobjectdir(monActor, -1)
- end
- elseif state == DuplicateState.FIGHT then
- this.SendAllStateInfo(mapId, configId, state, nextStateStartTime)
- elseif state == DuplicateState.FINISH then
- this.Settlement(mapId, configId)
- elseif state == DuplicateState.CLOSED then
- this.SetCurrentDupId(nil)
- closeactivity(DuplicateType.ROLAND_SEIGE)
- end
- end
- -- 副本3秒心跳
- function RolandSeige.Dup3SecondHeart(mapId, dupConfig, state)
- if state == DuplicateState.FIGHT then
- this.SendAllTaskPanel(mapId)
- end
- end
- --副本1秒钟心跳
- function RolandSeige.DupSecondHeart(mapId, dupConfig, state)
- if state == DuplicateState.FIGHT then
- if this.IsFinalPhase(mapId) then
- local areaStr = ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.OCCUPY_AREA)
- local areaStrSplit = string.split(areaStr, "#")
- local x = areaStrSplit[1]
- local y = areaStrSplit[2]
- local range = areaStrSplit[3]
- -- 获取圈内所有玩家
- local idList = getobjectinmap(mapId, x, y, range)
- if #idList <= 0 then
- this.SendAllUnionProgress(mapId, nil)
- return
- end
- local unionIds = {}
- -- 如果是守方,个人加积分
- for _, rid in pairs(idList) do
- local actor = getactor(rid, mapId)
- if not isdead(actor) then
- local camp = this.GetCamp(actor, mapId)
- if camp == RolandConst.CAMP_TYPE.DEFEND then
- RoleScoreDTO.addStay(actor, mapId, 1)
- end
- local unionId = getbaseinfo(actor, "guildid")
- if not table.contains(unionIds, unionId) then
- table.insert(unionIds, unionId)
- end
- end
- end
- -- 如果全部是同一个战盟,修改战盟攻守方,增加战盟进度条
- if #unionIds == 1 then
- local unionId = unionIds[1]
- local oldUnionId = this.GetDefendUnionId(mapId)
- -- 增加进度条
- local progressDTO = UnionProgressDTO.add(mapId, unionId, 1)
- if tostring(unionId) ~= tostring(oldUnionId) then
- -- 如果不是守方战盟,
- --1.清空守方战盟进度条;
- if oldUnionId ~= nil and oldUnionId > 0 then
- UnionProgressDTO.reset(mapId, oldUnionId)
- end
- --2.如果self进度条满了,换成守方,清空所有其他战盟进度条
- if UnionProgressDTO.isMax(progressDTO) then
- this.SetDefendUnionId(mapId, unionId)
- local allUnion = this.GetAllParticipatingUnions(mapId)
- for _, unionId0 in pairs(allUnion) do
- if tostring(unionId) ~= tostring(unionId0) then
- UnionProgressDTO.reset(mapId, unionId0)
- end
- end
- end
- end
- -- 通知全地图进度条信息
- this.SendAllUnionProgress(mapId, progressDTO)
- else
- -- 多个战盟在占领圈内
- this.SendAllUnionProgress(mapId, nil)
- end
- end
- end
- end
- -- 怪物死亡从副本中移除
- function RolandSeige.MapMonsterRemove(mapId, killer, monCfgId)
- this.SendAllPlayMonsterList(mapId)
- local taskInfo = this.GetAttackTask(mapId)
- local taskId = taskInfo[1]
- local taskType = taskInfo[2]
- if taskType == DuplicateTaskType.KILL_TARGET_MONSTER then
- local totalCount = taskInfo[3]
- local nowCount = taskInfo[4]
- local targetCfg = taskInfo[5]
- if monCfgId == targetCfg then
- nowCount = nowCount + 1
- end
- if nowCount >= totalCount then
- -- 当前任务完成,设置下一个任务
- local nextId = tonumber(ConfigDataManager.getTableValue("cfg_repTask", "nextID", "id", taskId))
- if nextId ~= nil then
- local defendTaskInfo = this.GetDefendTask(mapId)
- local nextDeId = tonumber(ConfigDataManager.getTableValue("cfg_repTask", "nextID", "id", defendTaskInfo[1]))
- this.SetAttackTask(mapId, nextId)
- this.SetDefendTask(mapId, nextDeId)
- -- 更新战斗模式
- local nextTaskType = ConfigDataManager.getTableValue("cfg_repTask", "type", "id", nextId)
- if tonumber(nextTaskType) == DuplicateTaskType.ROLAND_SEIGE_OCCUPY then
- -- 修改所有人的战斗模式
- local allPlayers = getmapplayer(mapId)
- for _, actor in pairs(allPlayers) do
- setplayersetting(actor, 1, 5)
- end
- end
- this.SendAllTaskPanel(mapId)
- end
- end
- end
- end
- -- @description 玩家进入副本后
- -- @param 玩家对象;地图唯一id;副本类型;副本阶段(1-准备 2-战斗 3-结算);下一阶段开始时间戳;配置id(cfg_rep的id)
- -- @return
- function RolandSeige.AfterEnterRoland(actor, mapId, state, nextStateStartTime, configId)
- -- 记录参与的玩家
- local rid = actor:toString()
- local selfUnionId = getbaseinfo(actor, "guildid")
- local roleScoreDTO = RoleScoreDTO.get(actor, mapId)
- if roleScoreDTO == nil then
- -- 不只是积分,需要修改
- roleScoreDTO = RoleScoreDTO.new(rid, selfUnionId)
- RoleScoreDTO.set(actor, mapId, roleScoreDTO)
- end
- -- 设置战盟进度条
- local progressDTO = UnionProgressDTO.get(mapId, selfUnionId)
- if progressDTO == nil then
- local dto = UnionProgressDTO.new(selfUnionId, false)
- UnionProgressDTO.set(mapId, selfUnionId, dto)
- end
- -- 修改战斗模式
- if this.IsFinalPhase(mapId) then
- setplayersetting(actor, 1, 5)
- else
- if this.GetCamp(actor, mapId) == RolandConst.CAMP_TYPE.ATTACK then
- setplayersetting(actor, 1, 11)
- else
- setplayersetting(actor, 1, 12)
- end
- end
- -- 发送副本阶段
- this.SendStateInfo(actor, configId, state, nextStateStartTime)
- -- 任务面板
- this.SendTaskPanel(actor, mapId)
- -- 怪物信息
- this.SendMonsterList(actor, mapId)
- -- if state == DuplicateState.PREPARE then
- -- elseif state == DuplicateState.FIGHT then
- -- elseif state == DuplicateState.FINISH then
- -- end
- end
- -- 玩家在罗兰峡谷修改战斗模式
- function RolandSeige.RolandSettingChange(actor, cType, value)
- if cType ~= 1 or (not RolandSeige.IsPlayerInRoland(actor)) then
- return
- end
- local mapId = getbaseinfo(actor, "unimapid")
- if this.IsFinalPhase(mapId) then
- if value ~= 5 then
- setplayersetting(actor, 1, 5)
- end
- else
- if this.GetCamp(actor, mapId) == RolandConst.CAMP_TYPE.ATTACK then
- if value ~= 11 then
- setplayersetting(actor, 1, 11)
- end
- else
- if value ~= 12 then
- setplayersetting(actor, 1, 12)
- end
- end
- end
- end
- -- 玩家退出副本
- function RolandSeige.OnQuitDup(actor, mapId, state, nextStateStartTime, configId)
- setplayersetting(actor, 1, 5)
- end
- -- 击杀玩家事件
- function RolandSeige.KillPlayer(actor, diePlayer)
- local mapId = getbaseinfo(actor, "unimapid")
- local dupInfo = getduplicate(mapId)
- if dupInfo == nil or dupInfo == "" then
- return
- end
- local type = dupInfo["type"]
- if type ~= DuplicateType.ROLAND_SEIGE then
- return
- end
- RoleScoreDTO.addKill(actor, mapId, 1)
- this.SendTaskPanel(actor, mapId)
- end
- -- @description 玩家复活事件
- -- @param 玩家对象
- function RolandSeige.PlayerRelive(actor)
- local mapId = getbaseinfo(actor, "unimapid")
- local dupInfo = getduplicate(mapId)
- if dupInfo == nil then
- return
- end
- local type = dupInfo["type"]
- if type ~= DuplicateType.ROLAND_SEIGE then
- return
- end
- local camp = this.GetCamp(actor, mapId)
- -- 复活后传送
- local x, y
- local taskInfo = this.GetAttackTask(mapId)
- local taskId = taskInfo[1]
- if camp == RolandConst.CAMP_TYPE.ATTACK then
- local relivePointStr = ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.ATTACK_RELIVE_POINT)
- local relivePointStrSplit = string.split(relivePointStr, "|")
- for _, value in pairs(relivePointStrSplit) do
- local valueSplit = string.split(value, "#")
- if tonumber(valueSplit[1]) == taskId then
- x = valueSplit[1]
- y = valueSplit[2]
- break
- end
- end
- elseif camp == RolandConst.CAMP_TYPE.DEFEND then
- local relivePointStr = ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.DEFEND_RELIVE_POINT)
- local relivePointStrSplit = string.split(relivePointStr, "#")
- x = relivePointStrSplit[1]
- y = relivePointStrSplit[2]
- end
- if x ~= nil and y ~= nil then
- maptransfer(actor, x, y, 0, 0, 0)
- else
- gameDebug.assertPrintTrace(false, actor:toString() .. "罗兰峡谷攻城战死亡复活传送未找到传送点!camp: " .. camp .. " ;taskId:" .. taskId)
- end
- end
- -- 攻击事件
- function RolandSeige.Attack(actor, fightData)
- local mapId = getbaseinfo(actor, "unimapid")
- local dupInfo = getduplicate(mapId)
- if dupInfo == nil then
- return
- end
- local type = dupInfo["type"]
- if type ~= DuplicateType.ROLAND_SEIGE then
- return
- end
- local casterType = fightData.castertype
- local targetType = fightData.targettype
- if casterType ~= MapObjectType.PLAYER and casterType ~= MapObjectType.PET then
- return
- end
- if casterType == MapObjectType.PET or casterType == MapObjectType.PARTNER then
- local masterId = getbaseinfo(actor, "master")
- actor = getactor(masterId, mapId)
- end
- local camp = this.GetCamp(actor, mapId)
- if camp == RolandConst.CAMP_TYPE.ATTACK and targetType == MapObjectType.MONSTER then
- -- 增加攻方攻击建筑的次数
- RoleScoreDTO.addAttackBuilding(actor, mapId, 1)
- end
- -- 累计伤害
- RoleScoreDTO.addHurt(actor, mapId, fightData.targethurt)
- this.SendTaskPanel(actor, mapId)
- end
- --------------------------------------------------------------------------------------------------------------------------
- -- 初始化攻城战数据
- function this.InitRolandData(mapId, configId)
- -- 攻守方任务
- local firstTaskStr = ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.FIRST_TASK)
- local firstTaskStrSplit = string.split(firstTaskStr, "#")
- local defendTask = tonumber(firstTaskStrSplit[2])
- local attackTask = tonumber(firstTaskStrSplit[1])
- this.SetAttackTask(mapId, attackTask)
- this.SetDefendTask(mapId, defendTask)
- -- 设置守方战盟
- local defendUnionId = this.GetLastOccupyUnionId()
- if defendUnionId == nil then
- defendUnionId = 0
- end
- this.SetDefendUnionId(mapId, defendUnionId)
- if defendUnionId ~= 0 then
- local progressDTO = UnionProgressDTO.new(defendUnionId, true)
- UnionProgressDTO.set(mapId, defendUnionId, progressDTO)
- end
- end
- function this.GetUnionListInRange(mapId)
- local unionIds = {}
- local areaStr = ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.OCCUPY_AREA)
- local areaStrSplit = string.split(areaStr, "#")
- local x = areaStrSplit[1]
- local y = areaStrSplit[2]
- local range = areaStrSplit[3]
- -- 获取圈内所有战盟
- local idList = getobjectinmap(mapId, x, y, range)
- for _, rid in pairs(idList) do
- local actor = getactor(rid, mapId)
- local unionId = getbaseinfo(actor, "guildid")
- if not table.contains(unionIds, unionId) then
- table.insert(unionIds, unionId)
- end
- end
- return unionIds
- end
- -- 获取个人积分排名
- function this.GetPlayerRank(actor, mapId)
- local ranking = this.GetPlayerRankList(mapId)
- return ranking[actor:toString()]
- end
- -- 获取玩家的个人积分排名列表
- -- @return 列表<玩家id字符串;排名>
- function this.GetPlayerRankList(mapId)
- local playerList = {}
- local allPlayers = this.GetAllParticipatingPlayers(mapId)
- for key, actor0 in pairs(allPlayers) do
- local score = RoleScoreDTO.calTotalScoreByActor(actor0, mapId)
- table.insert(playerList, { rid = actor0:toString(), score = score })
- end
- table.sort(
- playerList,
- function(a, b)
- return a.score > b.score
- end
- )
- -- 计算排名
- local ranks = {}
- local rank = 1 -- 当前排名
- for i = 1, #playerList do
- local player = playerList[i]
- -- 每次循环都增加排名
- ranks[player.rid] = rank
- rank = rank + 1
- end
- return ranks
- end
- -- 战盟排名
- function this.GetUnionRank(unionId, mapId)
- local ranking = this.GetUnionRankMap(mapId)
- return ranking[tostring(unionId)]
- end
- -- 获取战盟积分排名列表
- -- @return 列表<战盟id字符串;排名>
- function this.GetUnionRankMap(mapId)
- local union2Score = {}
- local allPlayers = this.GetAllParticipatingPlayers(mapId)
- for key, actor0 in pairs(allPlayers) do
- local score = RoleScoreDTO.calTotalScoreByActor(actor0, mapId)
- local unionId = tostring(getbaseinfo(actor0, "guildid"))
- if union2Score[unionId] == nil then
- union2Score[unionId] = score
- else
- union2Score[unionId] = score + union2Score[unionId]
- end
- end
- local scoreArray = {}
- for unionId, score in pairs(union2Score) do
- table.insert(scoreArray, { unionId = unionId, score = score })
- end
- table.sort(
- scoreArray,
- function(a, b)
- return a.score > b.score
- end
- )
- -- 计算排名
- local ranks = {}
- local rank = 1 -- 当前排名
- for i = 1, #scoreArray do
- local union = scoreArray[i]
- -- 每次循环都增加排名
- ranks[union.unionId] = rank
- rank = rank + 1
- end
- return ranks
- end
- -- 获取战盟积分排名列表
- -- @return 列表{{ unionId = unionId, score = score },....}
- function this.GetUnionRankList(mapId)
- local union2Score = {}
- local allPlayers = this.GetAllParticipatingPlayers(mapId)
- for key, actor0 in pairs(allPlayers) do
- local score = RoleScoreDTO.calTotalScoreByActor(actor0, mapId)
- local unionId = tostring(getbaseinfo(actor0, "guildid"))
- if union2Score[unionId] == nil then
- union2Score[unionId] = score
- else
- union2Score[unionId] = score + union2Score[unionId]
- end
- end
- local scoreArray = {}
- for unionId, score in pairs(union2Score) do
- table.insert(scoreArray, { unionId = unionId, score = score })
- end
- table.sort(
- scoreArray,
- function(a, b)
- return a.score > b.score
- end
- )
- return scoreArray
- end
- -- 是否是最后阶段
- function this.IsFinalPhase(mapId)
- local attackTaskInfo = this.GetAttackTask(mapId)
- local taskId = attackTaskInfo[1]
- local nextId = tonumber(ConfigDataManager.getTableValue("cfg_repTask", "nextID", "id", taskId))
- if nextId == nil or nextId == 0 then
- return true
- end
- return false
- end
- -- 结算
- function this.Settlement(mapId)
- local log = LogRecord.new()
- local winUninId
- if this.IsFinalPhase(mapId) then
- -- 守方战盟为胜利方
- local defendUnionId = this.GetDefendUnionId(mapId)
- if defendUnionId == nil or defendUnionId == 0 then
- -- 无守方
- -- 积分第一的为占领战盟,无盟主奖励
- local unionRankList = this.GetUnionRankList(mapId)
- local unionInfo = unionRankList[1]
- winUninId = unionInfo.unionId
- log.winType = "积分"
- else
- local unionInfo = getunioninfo(defendUnionId)
- local leaderId = unionInfo.leaderid
- local leaderActor = getactor(leaderId, mapId)
- local leaderRewardStr = ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.LEADER_REWARD)
- local leaderRewardStrSplit = string.toIntIntMap(leaderRewardStr, "#", "|")
- sendconfigmailbyrid(leaderActor, leaderActor:toString(), MailConfig.ROLAND_SEIGE_LEADER_REWARD, leaderRewardStrSplit)
- winUninId = defendUnionId
- log.winType = "占领"
- log.leader = leaderId
- end
- else
- winUninId = this.GetLastOccupyUnionId()
- end
- -- 设置占领战盟
- winUninId = winUninId or 0
- log.winUninId = winUninId
- this.SetLastOccupyUnionId(winUninId)
- -- 个人积分奖励
- local rank2Reward = {}
- local needScore = tonumber(ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.PERSONAL_LIMIT_SCORE))
- local personalRewardStr = ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.PERSONAL_REWARD)
- local personalRewardStrSplit = string.split(personalRewardStr, "|")
- for key, value in pairs(personalRewardStrSplit) do
- local valueSplit = string.split(value, "&")
- local rankList = string.split(valueSplit[1], "#")
- local startRank = tonumber(rankList[1])
- local endRank = tonumber(rankList[2])
- local totalReward = {}
- for j = 2, #valueSplit do
- local reward = string.split(valueSplit[j], "#")
- totalReward[tonumber(reward[1])] = tonumber(reward[2])
- end
- table.insert(rank2Reward, { startRank = startRank, endRank = endRank, rewards = totalReward })
- end
- -- 获取所有参与的玩家
- local allPlayers = this.GetAllParticipatingPlayers(mapId)
- for _, actor in pairs(allPlayers) do
- local selfUnionId = getbaseinfo(actor, "guildid")
- if tostring(selfUnionId) == tostring(winUninId) then
- -- 获胜
- local winRewardStr = ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.WIN_UNION_REWARD)
- local winRewardStrSplit = string.toIntIntMap(winRewardStr, "#", "|")
- sendconfigmailbyrid(actor, actor:toString(), MailConfig.ROLAND_SEIGE_WIN_UNION_REWARD, winRewardStrSplit)
- else
- --失败
- local failRewardStr = ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.FAIL_UNION_REWARD)
- local failRewardStrSplit = string.toIntIntMap(failRewardStr, "#", "|")
- sendconfigmailbyrid(actor, actor:toString(), MailConfig.ROLAND_SEIGE_FAIL_UNION_REWARD, failRewardStrSplit)
- end
- -- 个人积分奖励
- local ownScore = RoleScoreDTO.calTotalScoreByActor(actor, mapId)
- log.personalScoreList[actor:toString()] = ownScore
- local ranking = this.GetPlayerRankList(mapId)
- if ownScore >= needScore then
- local rank = ranking[actor:toString()]
- for _, rewardInfo in ipairs(rank2Reward) do
- if rank >= rewardInfo.startRank and rank <= rewardInfo.endRank then
- local rewards = rewardInfo.rewards
- sendconfigmailbyrid(actor, actor:toString(), MailConfig.ROLAND_SEIGE_PERSONAL_REWARD, rewards, rank)
- end
- end
- end
- end
- gameDebug.debug(LogRecord.log, log)
- end
- -- 获取玩家的阵营
- function this.GetCamp(actor, mapId)
- local defendUnionId = this.GetDefendUnionId(mapId)
- local selfUnionId = getbaseinfo(actor, "guildid")
- if tostring(defendUnionId) == tostring(selfUnionId) then
- return RolandConst.CAMP_TYPE.DEFEND
- else
- return RolandConst.CAMP_TYPE.ATTACK
- end
- end
- -- 是否可以开启
- function RolandSeige.CanOpenActivity()
- local openDays = getbaseinfo("serveropendays")
- local day, hour, minute = this.GetFirstOpenTime()
- if openDays < day then
- return false
- end
- return true
- end
- -- 获取首次开启时间
- function this.GetFirstOpenTime()
- local firstOpenTimeString = ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.FIRST_OPEN_TIME)
- local firstOpenTimeStringSplit = string.split(firstOpenTimeString, "#")
- local day = tonumber(firstOpenTimeStringSplit[1])
- local hour = tonumber(firstOpenTimeStringSplit[2])
- local minute = tonumber(firstOpenTimeStringSplit[3])
- return day, hour, minute
- end
- ---------------------------------------------------------- 响应 -----------------------------------------------------------------
- -- 响应单个玩家副本阶段
- function this.SendStateInfo(actor, repId, state, nextStateStartTime)
- sendluamsg(actor, LuaMessageIdToClient.RES_ROLAND_SEIGE_STATE, { repId, state, tostring(nextStateStartTime) })
- end
- -- 响应所有玩家副本阶段
- function this.SendAllStateInfo(mapId, repId, state, nextStateStartTime)
- local allPlayers = getmapplayer(mapId)
- if #allPlayers > 0 then
- for _, actor in pairs(allPlayers) do
- this.SendStateInfo(actor, repId, state, nextStateStartTime)
- end
- end
- end
- -- 响应单个玩家任务面板信息
- function this.SendTaskPanel(actor, mapId)
- local res = {}
- local selfCamp = this.GetCamp(actor, mapId)
- res.camp = selfCamp
- -- 任务信息
- local taskInfo
- if selfCamp == RolandConst.CAMP_TYPE.ATTACK then
- taskInfo = this.GetAttackTask(mapId)
- else
- taskInfo = this.GetDefendTask(mapId)
- end
- local taskId = taskInfo[1]
- local taskType = taskInfo[2]
- if taskType == DuplicateTaskType.KILL_TARGET_MONSTER then
- local targetMonCfg = taskInfo[5]
- local monsterList = mapbossinfo(mapId, -1, targetMonCfg)
- local minHP = 999999999
- local maxHP = 999999999
- for _, monInfo in pairs(monsterList) do
- local monHP = monInfo.hp
- if monHP < minHP then
- minHP = monHP
- end
- maxHP = monInfo.maxhp
- end
- res.nowCount = math.ceil((minHP / maxHP) * 100)
- res.totalCount = 100
- else
- res.nowCount = 0
- res.totalCount = 1
- end
- res.taskId = taskId
- -- 占领战盟
- local defendUnionId = this.GetDefendUnionId(mapId)
- if defendUnionId == nil or defendUnionId == 0 then
- res.unionName = "无"
- else
- --
- local progressDTO = UnionProgressDTO.get(mapId, defendUnionId)
- res.unionName = progressDTO.unionName
- end
- -- 所在战盟排名
- local unionId = getbaseinfo(actor, "guildid")
- res.unionRank = this.GetUnionRank(unionId, mapId)
- -- 个人排名
- res.selfRank = this.GetPlayerRank(actor, mapId)
- -- 个人积分
- res.selfScore = RoleScoreDTO.calTotalScoreByActor(actor, mapId)
- sendluamsg(actor, LuaMessageIdToClient.RES_ROLAND_SEIGE_TASK_PANEL, res)
- end
- -- 响应所有玩家任务面板信息
- function this.SendAllTaskPanel(mapId)
- local allPlayers = getmapplayer(mapId)
- if #allPlayers > 0 then
- for _, actor in pairs(allPlayers) do
- this.SendTaskPanel(actor, mapId)
- end
- end
- end
- -- 响应所有玩家战盟占领进度
- function this.SendAllUnionProgress(mapId, progressDTO)
- local allPlayers = getmapplayer(mapId)
- if #allPlayers > 0 then
- for _, actor in pairs(allPlayers) do
- sendluamsg(actor, LuaMessageIdToClient.RES_ROLAND_PROGRESS_INFO, progressDTO)
- end
- end
- end
- -- 响应玩家副本怪物信息
- function this.SendMonsterList(actor, mapId)
- local res = this.BuildResMonsterList(mapId)
- sendluamsg(actor, LuaMessageIdToClient.RES_ROLAND_MONSTER_LIST, res)
- end
- -- 响应所有玩家副本怪物信息
- function this.SendAllPlayMonsterList(mapId)
- local res = this.BuildResMonsterList(mapId)
- local allPlayers = getmapplayer(mapId)
- if #allPlayers > 0 then
- for _, actor in pairs(allPlayers) do
- sendluamsg(actor, LuaMessageIdToClient.RES_ROLAND_MONSTER_LIST, res)
- end
- end
- end
- function this.BuildResMonsterList(mapId)
- local res = {}
- local monList = getmapmon(mapId)
- for _, monActor in pairs(monList) do
- local oneRes = {}
- local monInfo = getmonsterinfo(monActor)
- oneRes.id = monInfo.id
- oneRes.cfg = monInfo.cfgid
- oneRes.x = monInfo.x
- oneRes.y = monInfo.y
- table.insert(res, oneRes)
- end
- return res
- end
- --------------------------------------------------------------------------------------------------------------------------
- ---------------------------------------------------------- 数据 -----------------------------------------------------------------
- -- 获取当前进行的攻城战副本id
- function this.GetCurrentDupId()
- local oldDupId = getsysvar(SystemVarConst.ROLAND_SEIGE.DUPLICATE_ID)
- return oldDupId
- end
- -- 设置当前进行的攻城战副本id
- function this.SetCurrentDupId(dupId)
- setsysvar(SystemVarConst.ROLAND_SEIGE.DUPLICATE_ID, dupId)
- end
- -- 获取上次占领战盟Id
- function this.GetLastOccupyUnionId()
- local unionId = getsysvar(SystemVarConst.ROLAND_SEIGE.LAST_OCCUPY_UNION_ID)
- return unionId
- end
- -- 设置上次占领战盟Id
- function this.SetLastOccupyUnionId(unionId)
- setsysvar(SystemVarConst.ROLAND_SEIGE.LAST_OCCUPY_UNION_ID, unionId)
- end
- -- 获取守方战盟id
- function this.GetDefendUnionId(mapId)
- local unionId = getenvirvar(mapId, DuplicateVarConst.ROLAND_SEIGE.DEFEND_UNION)
- return unionId
- end
- -- 设置守方战盟id
- function this.SetDefendUnionId(mapId, unionId)
- setenvirvar(mapId, DuplicateVarConst.ROLAND_SEIGE.DEFEND_UNION, unionId)
- end
- -- 获取守方任务
- function this.GetDefendTask(mapId)
- local defendTaskInfo = getenvirvar(mapId, DuplicateVarConst.ROLAND_SEIGE.DEFEND_TASK)
- return defendTaskInfo
- end
- -- 设置守方任务
- function this.SetDefendTask(mapId, taskId)
- local defendTaskInfo = DuplicateCommon.GenDupTaskInfoCommon(taskId)
- setenvirvar(mapId, DuplicateVarConst.ROLAND_SEIGE.DEFEND_TASK, defendTaskInfo)
- end
- -- 获取攻方任务
- function this.GetAttackTask(mapId)
- local attackTaskInfo = getenvirvar(mapId, DuplicateVarConst.ROLAND_SEIGE.ATTACK_TASK)
- return attackTaskInfo
- end
- -- 设置攻方任务
- function this.SetAttackTask(mapId, taskId)
- local attackTaskInfo = DuplicateCommon.GenDupTaskInfoCommon(taskId)
- setenvirvar(mapId, DuplicateVarConst.ROLAND_SEIGE.ATTACK_TASK, attackTaskInfo)
- end
- -- 获取所有参与的玩家{actor,...}
- function this.GetAllParticipatingPlayers(mapId)
- local allPlayers = getdupparticipants(mapId)
- return allPlayers
- end
- -- 获取所有参与的战盟
- function this.GetAllParticipatingUnions(mapId)
- local allUnion = {}
- local allPlayers = this.GetAllParticipatingPlayers(mapId)
- for _, actor in pairs(allPlayers) do
- local unionId = getbaseinfo(actor, "guildid")
- if not table.contains(allUnion, unionId) then
- table.insert(allUnion, unionId)
- end
- end
- return allUnion
- end
- --------------------------------------------------------------------------------------------------------------------------
- function testenterroland(actor)
- RolandSeige.ReqEnterDupLicate(actor)
- end
- function testcloseroland(actor)
- local mapId = getbaseinfo(actor, "unimapid")
- setduplicatestate(mapId, SetDuplicateStateConst.TO_FINISH)
- end
- function testfightroland(actor)
- local mapId = getbaseinfo(actor, "unimapid")
- setduplicatestate(mapId, SetDuplicateStateConst.TO_FIGHT)
- end
- function testreqroland(actor)
- RolandSeige.ReqMainPanel(actor)
- end
- function testclearroland(actor)
- this.SetLastOccupyUnionId(0)
- end
|