Просмотр исходного кода

Merge branch 'dianfengzhanchang' into miniApp

# Conflicts:
#	webServer/src/channels/factory/ChannelFactory.ts
#	webServer/src/config/channelConfig.ts
#	webServer/src/config/thirdParams.ts
flowerpig 7 месяцев назад
Родитель
Сommit
41e6cf0226
100 измененных файлов с 8817 добавлено и 314 удалено
  1. 7 0
      script/common/CommonDefine.lua
  2. 1 0
      script/common/DB.lua
  3. 123 1
      script/common/InnerHandler.lua
  4. 162 3
      script/common/InnerProto.lua
  5. 25 4
      script/common/InnerProtoID.lua
  6. 9 2
      script/common/Lang.lua
  7. 6 0
      script/common/Log.lua
  8. 18 0
      script/common/LogDefine.lua
  9. 90 15
      script/common/ProtoID.lua
  10. 8 0
      script/common/Util.lua
  11. 1 1
      script/core/DataCache.lua
  12. 1 0
      script/core/ObjHuman.lua
  13. 1 1
      script/core/RoleDel.lua
  14. 3 3
      script/core/Timer.lua
  15. 14 0
      script/core/commonOperate.lua
  16. 2 1
      script/excel/ssecy/combat.lua
  17. 22 0
      script/excel/ssecy/peakBattlefieldReward.lua
  18. 1 1
      script/merge/MergeServerCS.lua
  19. 52 23
      script/merge/MergeServerDefine.lua
  20. 25 1
      script/module/WeekendLoopActivity/WeekendLoopActCard.lua
  21. 38 0
      script/module/WeekendLoopActivity/WeekendLoopActHeroStar.lua
  22. 2 1
      script/module/WeekendLoopActivity/WeekendLoopActManager.lua
  23. 12 2
      script/module/absAct/Abs365CardLogic.lua
  24. 13 6
      script/module/absAct/AbsActLogic.lua
  25. 25 1
      script/module/absAct/AbsExcellentGiftLogic.lua
  26. 12 2
      script/module/absAct/AbsWeeklyCardLogic.lua
  27. 17 2
      script/module/absAct/BusOneActivityBuy.lua
  28. 16 1
      script/module/absAct/BusOneActivityYuanZheng.lua
  29. 199 0
      script/module/absAct/BusThreeActDice.lua
  30. 146 0
      script/module/absAct/BusThreeActDiscountStore.lua
  31. 286 0
      script/module/absAct/BusThreeActGrandGift.lua
  32. 577 0
      script/module/absAct/BusThreeActTask.lua
  33. 377 0
      script/module/absAct/CommonActBoss.lua
  34. 224 0
      script/module/absAct/CommonActCharge.lua
  35. 280 0
      script/module/absAct/CommonActFindTreasure.lua
  36. 147 0
      script/module/absAct/CommonActShop.lua
  37. 1 1
      script/module/absAct/CycleHeroSendGift.lua
  38. 52 6
      script/module/absAct/CycleMakeFood.lua
  39. 29 6
      script/module/absAct/CycleSevenDayTask.lua
  40. 12 7
      script/module/absAct/DoubleChargeLogic.lua
  41. 11 9
      script/module/absAct/FestivalSevenDayCardLogic.lua
  42. 95 2
      script/module/absAct/Handler.lua
  43. 13 0
      script/module/absAct/HeroGrowUp.lua
  44. 26 2
      script/module/absAct/MangHeLogic.lua
  45. 36 2
      script/module/absAct/NewHeroLogic.lua
  46. 47 17
      script/module/absAct/PremiumGiftLogic.lua
  47. 199 2
      script/module/absAct/Proto.lua
  48. 10 10
      script/module/absAct/SingleReachLogic.lua
  49. 41 5
      script/module/absAct/SpecialCustomLogic.lua
  50. 925 0
      script/module/areaBattle/AreaBattleCS.lua
  51. 245 0
      script/module/areaBattle/AreaBattleDB.lua
  52. 60 0
      script/module/areaBattle/AreaBattleDefine.lua
  53. 600 0
      script/module/areaBattle/AreaBattleNS.lua
  54. 21 0
      script/module/areaBattle/Handler.lua
  55. 115 0
      script/module/areaBattle/Proto.lua
  56. 73 3
      script/module/bag/BagLogic.lua
  57. 21 12
      script/module/bag/Grid.lua
  58. 8 0
      script/module/bag/Handler.lua
  59. 4 1
      script/module/bag/ItemDefine.lua
  60. 1 1
      script/module/bag/ItemLogic.lua
  61. 21 0
      script/module/bag/Proto.lua
  62. 83 7
      script/module/bag/SuipianLogic.lua
  63. 47 0
      script/module/battleDataManager/BattleDataCS.lua
  64. 68 0
      script/module/battleDataManager/BattleDataNS.lua
  65. 6 0
      script/module/billboard/BillboardLogic.lua
  66. 1 1
      script/module/chat/Gm.lua
  67. 13 0
      script/module/chengjiu/ChengjiuLogic.lua
  68. 46 6
      script/module/combat/BeSkill.lua
  69. 223 35
      script/module/combat/CombatBuff.lua
  70. 16 4
      script/module/combat/CombatCalc.lua
  71. 27 2
      script/module/combat/CombatDefine.lua
  72. 113 14
      script/module/combat/CombatImpl.lua
  73. 207 13
      script/module/combat/CombatLogic.lua
  74. 280 0
      script/module/combat/CombatLogicCS.lua
  75. 53 3
      script/module/combat/CombatObj.lua
  76. 89 19
      script/module/combat/CombatPosLogic.lua
  77. 33 1
      script/module/combat/CombatVideo.lua
  78. 11 0
      script/module/combat/Handler.lua
  79. 0 12
      script/module/combat/JibanLogic.lua
  80. 27 2
      script/module/combat/Proto.lua
  81. 87 2
      script/module/combat/Skill.lua
  82. 30 2
      script/module/combat/TargetMode.lua
  83. 126 12
      script/module/dailyTask/HonorJourney.lua
  84. 3 0
      script/module/drawCard/DrawCardLogic.lua
  85. 17 0
      script/module/drawCard/Handler.lua
  86. 24 1
      script/module/drawCard/Proto.lua
  87. 13 3
      script/module/drawCard/RecommendLineup.lua
  88. 301 0
      script/module/drawCard/UnlimitDrawLogic.lua
  89. 5 2
      script/module/drill/DrillDB.lua
  90. 6 6
      script/module/drill/DrillLogic.lua
  91. 623 0
      script/module/elf/ElfLogic.lua
  92. 24 0
      script/module/elf/Handler.lua
  93. 92 0
      script/module/elf/Proto.lua
  94. 2 2
      script/module/equip/EquipLogic.lua
  95. 251 0
      script/module/equip/EquipWash.lua
  96. 21 0
      script/module/equip/Handler.lua
  97. 49 1
      script/module/equip/Proto.lua
  98. 6 2
      script/module/guide/GuideLogic.lua
  99. 19 1
      script/module/hero/Handler.lua
  100. 167 4
      script/module/hero/HeroLogic.lua

+ 7 - 0
script/common/CommonDefine.lua

@@ -8,9 +8,16 @@ CHANNEL_TAG_SANLI_IOS = 3        -- 三狸iOS
 CHANNEL_TAG_SANLI_QQ = 4         -- 三狸QQ大厅
 CHANNEL_TAG_SANLI_H5= 5          -- 三狸H5
 CHANNEL_TAG_SANLI_H5_4399 = 6    -- 三狸H5-4399
+
+
+
+
+SEA_CHANNEL_ARR = {13}  -- 海外渠道
+
 ----------------------------------------------------------------------------
 
 
+
 MAX_ONLINE_COUNT = 5000 		--	最大同时在线人数
 
 -- 断开连接提示码

+ 1 - 0
script/common/DB.lua

@@ -35,6 +35,7 @@ db_lost_temple          =   Config.DB_NAME .. ".lost_temple"         -- 神庙
 db_common_rank			= 	Config.DB_NAME .. ".common_rank"         -- 通用排行榜
 db_middle_rank			=	Config.DB_NAME .. ".middle_rank"		 -- 中心服排行榜数据
 db_gods_area			=	Config.DB_NAME .. ".godsArea"			 -- 诸神圣域
+db_area_battle			= 	Config.DB_NAME .. ".areaBattle"			 -- 战区争霸
 -- 加db第一步 请先确认是否要建对应字段的索引 第二步请确认合服逻辑是否要修改 
 
 function init()

+ 123 - 1
script/common/InnerHandler.lua

@@ -25,8 +25,15 @@ local MiddleCommonRank = require("middle.MiddleCommonRank")
 local BanLogic = require("scene.BanLogic")
 local JjcNewLadderMidder = require("jjcnewladder.jjcNewLadderMiddle")
 local RebateLogic = require("platform.RebateLogic")
+local ServerCommerceActPeakBettleMiddle = require("serverCommerce.ServerCommerceActPeakBettleMiddle")
 local GodsAreaNS = require("godsArea.GodsAreaNS")
 local GodsAreaCS = require("godsArea.GodsAreaCS")
+local BattleDataNS = require("battleDataManager.BattleDataNS")
+local BattleDataCS = require("battleDataManager.BattleDataCS")
+local AreaBattleCS = require("areaBattle.AreaBattleCS")
+local AreaBattleNS = require("areaBattle.AreaBattleNS")
+
+
 
 function LW_HELLO(fd, msg)
 	if _G.is_middle ~= true then return end
@@ -78,6 +85,7 @@ end
 
 
 ----------------------------------------通用协议---------------------------------------
+
 --------------- 战斗录像--------------------------------------
 -- 向跨服查询录像数据
 function LW_COMBAT_VIDEO_QUERY(fd, msg)
@@ -96,6 +104,16 @@ function LW_COMBAT_VIDEO_SAVE(fd, msg)
 end
 --------------------------------------------------------------
 
+-- 跨服通知普通服上传战斗数据
+function WL_COMBAT_DATA(fd, msg)
+    BattleDataNS.CreateBattleData(fd, msg)
+end
+
+function LW_COMBAT_DATA(fd, msg)
+    if _G.is_middle ~= true then return end
+    BattleDataCS.BattleDataHandleManager(fd, msg)
+end
+
 --------------------------------------------------------------------------------------
 
 
@@ -562,6 +580,51 @@ end
 
 -------------------- 天梯赛结束 ---------------------------
 
+-------------------- 巅峰战场跨服协议开始 ---------------------------
+-- 普通服请求跨服排名数据(普通->中心)
+function LW_PEAK_BATTLEFIELD_QUERY_RANK_O2C(fd, msg)
+    if _G.is_middle ~= true then return end
+    ServerCommerceActPeakBettleMiddle.LW_PEAK_BATTLEFIELD_QUERY_RANK_O2C(fd, msg)
+end
+
+-- 请求跨服排名数据(中心->数据服)
+function WL_PEAK_BATTLEFIELD_QUERY_RANK_C2D(fd, msg)
+    ServerCommerceActPeakBettleMiddle.WL_PEAK_BATTLEFIELD_QUERY_RANK_C2D(fd, msg)
+end
+
+-- 请求跨服排名数据(数据服->中心)
+function LW_PEAK_BATTLEFIELD_QUERY_RANK_D2C(fd, msg)
+    if _G.is_middle ~= true then return end
+    ServerCommerceActPeakBettleMiddle.LW_PEAK_BATTLEFIELD_QUERY_RANK_D2C(fd, msg)
+end
+
+-- 获取到跨服排名数据(中心->普通)
+function WL_PEAK_BATTLEFIELD_QUERY_RANK_C2O(fd, msg)
+    ServerCommerceActPeakBettleMiddle.WL_PEAK_BATTLEFIELD_QUERY_RANK_C2O(fd, msg)
+end
+
+-- 普通服通知排名变化(普通->中心)
+function LW_PEAK_BATTLEFIELD_RANK_CHANGE_O2C(fd, msg)
+    if _G.is_middle ~= true then return end
+    ServerCommerceActPeakBettleMiddle.LW_PEAK_BATTLEFIELD_RANK_CHANGE_O2C(fd, msg)
+end
+
+-- 排名变化通知(中心->数据服)
+function WL_PEAK_BATTLEFIELD_RANK_CHANGE_C2D(fd, msg)
+    ServerCommerceActPeakBettleMiddle.WL_PEAK_BATTLEFIELD_RANK_CHANGE_C2D(fd, msg)
+end
+
+-- 发送排名奖励(数据服->中心)
+function LW_PEAK_BATTLEFIELD_SEND_RANK_REWARD_D2C(fd, msg)
+    if _G.is_middle ~= true then return end
+    ServerCommerceActPeakBettleMiddle.LW_PEAK_BATTLEFIELD_SEND_RANK_REWARD_D2C(fd, msg)
+end
+
+-- 发送排名奖励(中心->普通)
+function WL_PEAK_BATTLEFIELD_SEND_RANK_REWARD_C2O(fd, msg)
+    ServerCommerceActPeakBettleMiddle.WL_PEAK_BATTLEFIELD_SEND_RANK_REWARD_C2O(fd, msg)
+end
+-------------------- 巅峰战场跨服协议结束 ---------------------------
 
 -------------------- 返利开始 ---------------------------
 -- 向跨服查询该角色能否返利
@@ -654,4 +717,63 @@ function WL_GODSATREA_UPDATE_PLAYER_INFO(fd, msg)
     GodsAreaNS.NS_UpdatePlayerBaseInfo(msg.playerUid)
 end
 
-----------------------------------------------------------
+----------------------------------------------------------
+
+-------------------------战区争霸-------------------------
+
+-- 跨服通知普通服, 争霸活动开始了
+function WL_AREABATTLE_OPEN(fd, msg)
+    AreaBattleNS.C2N_BattleStart()
+end
+-- 普通服报名参加争霸活动
+function LW_AREABATTLE_JOIN_BATTLE(fd, msg)
+    if _G.is_middle ~= true then return end
+    AreaBattleCS.N2C_JoinBattle(msg)
+end
+
+
+-- 请求争霸活动基本信息
+function LW_AREABATTLE_BASEINFO_QUERY(fd, msg)
+    if _G.is_middle ~= true then return end
+    AreaBattleCS.N2C_GetBaseInfo(msg)
+end
+function WL_AREABATTLE_BASEINFO_QUERY(fd, msg)
+    AreaBattleNS.C2N_BaseInfo(msg)
+end
+
+
+-- 请求本服参战玩家列表
+function LW_AREABATTLE_JOINPLAYER_QUERY(fd, msg)
+    if _G.is_middle ~= true then return end
+    AreaBattleCS.N2C_GetJoinPlayerArr(msg)
+end
+function WL_AREABATTLE_JOINPLAYER_QUERY(fd, msg)
+    AreaBattleNS.C2N_JoinPlayerArr(msg)
+end
+
+
+-- 请求本轮活动区服匹配列表
+function LW_AREABATTLE_MATCHLIST_QUERY(fd, msg)
+    if _G.is_middle ~= true then return end
+    AreaBattleCS.N2C_GetMatchList(msg)
+end
+function WL_AREABATTLE_MATCHLIST_QUERY(fd, msg)
+    AreaBattleNS.C2N_MatchList(msg)
+end
+
+
+
+-- 请求本服战斗录像的展示数据
+function LW_AREABATTLE_VIDEOSHOW_QUERY(fd, msg)
+    if _G.is_middle ~= true then return end
+    AreaBattleCS.N2C_GetVideoShowData(msg)
+end
+function WL_AREABATTLE_VIDEOSHOW_QUERY(fd, msg)
+    AreaBattleNS.C2N_VideoShowData(msg)
+end
+
+
+-- 跨服通知普通服发奖
+function WL_AREABATTLE_SEND_REWARD(fd, msg)
+    AreaBattleNS.C2N_SendReward(msg)
+end

+ 162 - 3
script/common/InnerProto.lua

@@ -68,6 +68,27 @@ LW_COMBAT_VIDEO_SAVE = {
 
 --------------------------------------------------------------
 
+
+-----------------获取战斗数据----------------------------------
+WL_COMBAT_DATA = {
+  {"playerUuid",                    "string"},    -- 玩家uuid
+  {"moduleTag",                     "int"},       -- 请求模块标识
+  {"combatType",                    "int"},       -- 战斗类型
+  {"extraArgs",                     "table"},     -- 额外参数
+}
+
+LW_COMBAT_DATA = {
+  {"errCode",                       "int"},       -- 错误码,1:正确,-1: 没有对应类型的战斗数据
+  {"moduleTag",                     "int"},       -- 请求模块标识
+  {"extraArgs",                     "table"},     -- 额外参数
+  {"objList",                       "table"},
+  {"helpList",                      "table"},
+  {"roleBase",                      "table"},
+  {"formation",                     "int"},
+  {"jiBan",                         "table"},
+  {"elfList",                        "table"}
+}
+
 -----------------------------------------------------------------------------------------
 
 
@@ -214,7 +235,8 @@ LW_COMBAT_GETINFO_SEND =
   {"tHelpList",           "table"},
   {"tRoleBase",           "table"},
   {"formation",           "int"},
-  {"tJiBan",              "table"}
+  {"tJiBan",              "table"},
+  {"tElfList",            "table"},
 }
 
 WL_COMBAT_GETINFO_SEND = 
@@ -225,7 +247,8 @@ WL_COMBAT_GETINFO_SEND =
   {"tHelpList",           "table"},
   {"tRoleBase",           "table"},
   {"formation",           "int"},
-  {"tJiBan",              "table"}
+  {"tJiBan",              "table"},
+  {"tElfList",            "table"},
 }
 
 -------------------- 请求跨服切磋结束 ---------------------------
@@ -869,4 +892,140 @@ WL_GODSATREA_UPDATE_PLAYER_INFO = {
 }
 
 
----------------------------------------------------------------------
+---------------------------------------------------------------------
+
+---------------------------------战区争霸----------------------------
+
+-- 跨服通知普通服活动开启
+WL_AREABATTLE_OPEN = {
+}
+
+-- 普通服报名参加争霸活动
+LW_AREABATTLE_JOIN_BATTLE = {
+  {"sourceServerId",        "int"},        -- 参战服务器Id
+  {"joinBattleArray",       "table"},      -- 参战玩家列表
+}
+
+
+-- 普通服请求争霸活动的基本数据
+LW_AREABATTLE_BASEINFO_QUERY = {
+  {"sourceServerId",        "int"},
+  {"playerUuid",             "string"},      -- 玩家uuid
+}
+WL_AREABATTLE_BASEINFO_QUERY = {
+  {"stage",                         "int"},            -- 当前阶段, 0-休战, 1-准备, 2- 战斗, 3-发奖
+  {"startTime",                     "int"},            -- 本轮活动开始时间
+  {"endTime",                      "int"},            -- 本轮活动结束时间
+  {"playerUuid",                   "string"},      -- 玩家uuid
+}
+
+
+-- 普通服请求本服参与争霸活动的玩家数据
+LW_AREABATTLE_JOINPLAYER_QUERY = {
+  {"sourceServerId",        "int"},
+  {"playerUuid",             "string"},      -- 玩家uuid
+}
+WL_AREABATTLE_JOINPLAYER_QUERY = {
+  {"errCode",             "int"}, -- 错误码,0: 正常, -1: 本服每次没有参加战斗 
+  {"playerArray",        "table"},
+  {"playerUuid",          "string"},      -- 玩家uuid
+}
+
+
+-- 普通服请求参与本轮活动的区服的匹配列表
+LW_AREABATTLE_MATCHLIST_QUERY = {
+  {"sourceServerId",        "int"},
+  {"playerUuid",             "string"},      -- 玩家uuid
+}
+WL_AREABATTLE_MATCHLIST_QUERY = {
+  {"matchList",        "table"},
+  {"playerUuid",             "string"},      -- 玩家uuid
+}
+
+
+-- 跨服通知普通服发奖
+WL_AREABATTLE_SEND_REWARD = {
+  {"srvBattleRes",        "table"}, -- 本服战斗结果
+}
+
+
+-- 普通服请求本服相关的录像展示数据
+LW_AREABATTLE_VIDEOSHOW_QUERY = {
+  {"sourceServerId",        "int"},
+  {"playerUuid",             "string"},      -- 玩家uuid
+}
+WL_AREABATTLE_VIDEOSHOW_QUERY = {
+  {"errCode",               "int"},     -- 错误码,0: 正常, -1: 本服每次没有参加战斗, -2: 录像数据还没产生,请稍后再尝试
+  {"videoShowData",         "table"},   -- 录像数据
+  {"srvInfo",               "table"},   -- 区服数据
+  {"playerUuid",            "string"},  -- 玩家uuid
+}
+
+--------------------- 巅峰战场跨服协议开始 -----------------------------------
+-- 普通服请求跨服排名数据(普通->中心)
+LW_PEAK_BATTLEFIELD_QUERY_RANK_O2C = {
+  {"nSrcServerID",          "int"},       -- 服务器ID
+  {"nRankType",             "int"},       -- 排名类型(1=个人排名,2=服务器排名)
+}
+
+-- 请求跨服排名数据(中心->数据服)
+WL_PEAK_BATTLEFIELD_QUERY_RANK_C2D = {
+  {"nSrcServerID",          "int"},       -- 服务器ID
+  {"nRankType",             "int"},       -- 排名类型
+}
+
+-- 请求跨服排名数据(数据服->中心)
+LW_PEAK_BATTLEFIELD_QUERY_RANK_D2C = {
+  {"nSrcServerID",          "int"},       -- 服务器ID
+  {"nRankType",             "int"},       -- 排名类型
+  {"nIsEnd",                "int"},       -- 是否发送完成 0 未 1 发送完
+  {"tRankInfo",             "table"},     -- 排行榜数据
+  {"nFirst",                "int"},       -- 首次发送 1 是 0 否
+}
+
+-- 获取到跨服排名数据(中心->普通)
+WL_PEAK_BATTLEFIELD_QUERY_RANK_C2O = {
+  {"nFirst",                "int"},       -- 首次发送 1 是 0 否
+  {"nIsEnd",                "int"},       -- 是否发送完成 0 未 1 发送完
+  {"tRankInfo",             "table"},     -- 排行榜数据
+}
+
+-- 普通服通知排名变化(普通->中心)
+LW_PEAK_BATTLEFIELD_RANK_CHANGE_O2C = {
+  {"uuid",                  "string"},    -- 玩家uuid
+  {"name",                  "string"},    -- 玩家名字
+  {"head",                  "int"},       -- 玩家头像ID
+  {"headFrame",             "int"},       -- 玩家头像框
+  {"nSrcServerID",          "int"},       -- 服务器ID
+  {"nRank",                 "int"},       -- 当前排名
+  {"nValue",                "int"},       -- 排名值(如积分等)
+  {"servername",            "string"},    -- 服务器名称
+}
+
+-- 排名变化通知(中心->数据服)
+WL_PEAK_BATTLEFIELD_RANK_CHANGE_C2D = {
+  {"uuid",                  "string"},    -- 玩家uuid
+  {"name",                  "string"},    -- 玩家名字
+  {"head",                  "int"},       -- 玩家头像ID
+  {"headFrame",             "int"},       -- 玩家头像框
+  {"nSrcServerID",          "int"},       -- 服务器ID
+  {"nRank",                 "int"},       -- 当前排名
+  {"nValue",                "int"},       -- 排名值
+  {"servername",            "string"},    -- 服务器名称
+}
+
+-- 发送排名奖励(数据服->中心)
+LW_PEAK_BATTLEFIELD_SEND_RANK_REWARD_D2C = {
+  {"uuid",                  "string"},    -- 玩家uid
+  {"nServerID",             "int"},       -- 服务器ID
+  {"nRank",                 "int"},       -- 排名
+  {"tReward",               "table"},     -- 奖励列表
+}
+
+-- 发送排名奖励(中心->普通)
+WL_PEAK_BATTLEFIELD_SEND_RANK_REWARD_C2O = {
+  {"uuid",                  "string"},    -- 玩家uid
+  {"nRank",                 "int"},       -- 排名
+  {"tReward",               "table"},     -- 奖励列表
+}
+--------------------- 巅峰战场跨服协议结束 -----------------------------------

+ 25 - 4
script/common/InnerProtoID.lua

@@ -89,12 +89,11 @@ _ENV[86] = 'LW_JJC_NEWLADDER_QUERY_WORSHIP_D2C'
 _ENV[87] = 'WL_JJC_NEWLADDER_QUERY_WORSHIP_C20'
 _ENV[88] = 'LW_JJC_NEWLADDER_QUERY_WORSHIP_O2C'
 _ENV[89] = 'WL_JJC_NEWLADDER_QUERY_WORSHIP_C2D'
-
-
 _ENV[90] = 'LW_COMBAT_VIDEO_QUERY'
 _ENV[91] = 'WL_COMBAT_VIDEO_QUERY'
 _ENV[92] = 'LW_COMBAT_VIDEO_SAVE'
-
+_ENV[93] = 'WL_COMBAT_DATA'
+_ENV[94] = 'LW_COMBAT_DATA'
 
 _ENV[100] = 'LW_GODSATREA_QUERY_RANKLIST'
 _ENV[101] = 'WL_GODSATREA_QUERY_RANKLIST'
@@ -109,4 +108,26 @@ _ENV[109] = 'WL_GODSATREA_QUERY_RANK_VIDEO'
 _ENV[110] = 'LW_GODSATREA_UPDATE_PLAYER_BASE_INFO'
 _ENV[111] = 'LW_GODSATREA_UPDATE_PLAYER_HERO_INFO'
 _ENV[112] = 'WL_GODSATREA_BROCAST_REWARD'
-_ENV[113] = 'WL_GODSATREA_UPDATE_PLAYER_INFO'
+_ENV[113] = 'WL_GODSATREA_UPDATE_PLAYER_INFO'
+
+_ENV[114] = 'WL_AREABATTLE_OPEN'
+_ENV[115] = 'LW_AREABATTLE_JOIN_BATTLE'
+_ENV[116] = 'LW_AREABATTLE_BASEINFO_QUERY'
+_ENV[117] = 'WL_AREABATTLE_BASEINFO_QUERY'
+_ENV[118] = 'LW_AREABATTLE_JOINPLAYER_QUERY'
+_ENV[119] = 'WL_AREABATTLE_JOINPLAYER_QUERY'
+_ENV[120] = 'LW_AREABATTLE_MATCHLIST_QUERY'
+_ENV[121] = 'WL_AREABATTLE_MATCHLIST_QUERY'
+_ENV[122] = 'WL_AREABATTLE_SEND_REWARD'
+_ENV[123] = 'LW_AREABATTLE_VIDEOSHOW_QUERY'
+_ENV[124] = 'WL_AREABATTLE_VIDEOSHOW_QUERY'
+
+-- 巅峰战场跨服协议
+_ENV[125] = 'LW_PEAK_BATTLEFIELD_QUERY_RANK_O2C'
+_ENV[126] = 'WL_PEAK_BATTLEFIELD_QUERY_RANK_C2D'
+_ENV[127] = 'LW_PEAK_BATTLEFIELD_QUERY_RANK_D2C'
+_ENV[128] = 'WL_PEAK_BATTLEFIELD_QUERY_RANK_C2O'
+_ENV[129] = 'LW_PEAK_BATTLEFIELD_RANK_CHANGE_O2C'
+_ENV[130] = 'WL_PEAK_BATTLEFIELD_RANK_CHANGE_C2D'
+_ENV[131] = 'LW_PEAK_BATTLEFIELD_SEND_RANK_REWARD_D2C'
+_ENV[132] = 'WL_PEAK_BATTLEFIELD_SEND_RANK_REWARD_C2O'

+ 9 - 2
script/common/Lang.lua

@@ -88,6 +88,8 @@ HERO_BAG_BUY_CAP_NO_CNT = [[购买次数达到上限]]
 HERO_JUEXING_ERR_QUALITY = [[英雄品阶满级才能升星]]
 HERO_JUEXING_ERR_HEROLV = [[角色等级{1}级或世界等级{2}级才能继续升星]]
 HERO_JUEXING_ERR_HEROLV2 = [[角色等级{1}级才能继续升星]]
+HERO_UPSTAR_EXTRA_COND = [[需要>={1}星的英雄达到{2}个才可升星]]
+
 HERO_UPGRADE_ERR_FULL = [[英雄品阶已满]]
 HERO_CHONGSHENG_ERR_LOCK = [[该英雄已被锁定,不可重生]]
 HERO_CHONGSHENG_ERR_ID = [[该英雄不能重生]]
@@ -775,7 +777,7 @@ RELIC_ALREADY_ACTIVATED = [[遗物已激活]]
 RELIC_NOT_ACTIVATED = [[遗物未激活]]
 RELIC_STAR_TOO_LOW = [[遗物等级太低]]
 RELIC_MAX_STAR = [[超出最大上限]]
-COMMON_ARGUMENT_ERROR= [[操作错误]]
+-- COMMON_ARGUMENT_ERROR= [[操作错误]]
 RELIC_UPGRADE_ITEM_LACK = [[升星所需物品不足]]
 RELIC_HERO_STAR_LIMIT = [[英雄等级不足]]
 RELIC_NOT_EQUIPPED = [[遗物未装备]]
@@ -810,4 +812,9 @@ DATA_OLD = [[请获取最新数据后再操作]]
 CHALLENGE_STRONG_ONE = [[无需向下级神位发起挑战]]
 CHALLENGING_SELF = [[自己正在被挑战]]
 CHALLENGING_TARGET = [[有玩家正在挑战此神位]]
--------------------------------------
+-------------------------------------
+
+---------------精灵------------
+ELF_NOT_ACTIVATE = [[精灵未激活]]
+ELF_MAX_STAR = [[精灵已经是最高星级]]
+ELF_SANME_ERR = [[不能同时上阵相同精灵]]

+ 6 - 0
script/common/Log.lua

@@ -77,6 +77,12 @@ function init()
     --[[月光宝盒]] LOGID_OSS_STORAGEBOx = lua_log.reg("log/oss_storageBox","",300)   -- 月光宝盒
     --[[诸神圣域-战斗]] LOGID_OSS_GODSAREA_CHALLENGE = lua_log.reg("log/oss_godArea_challenge","",300)
     --[[诸神圣域-邮件]] LOGID_OSS_GODSAREA_MAIL = lua_log.reg("log/oss_godArea_mail","",300)
+
+    --[[战区争霸-战斗]] LOGID_OSS_AREABATTLE_BATTLE = lua_log.reg("log/oss_areaBattle_battle","",300)
+    --[[战区争霸-奖励]] LOGID_OSS_AREABATTLE_AWARD = lua_log.reg("log/oss_areaBattle_award","",300)
+
+    --[[精灵日志]] LOGID_OSS_ELF = lua_log.reg("log/oss_elf","playerUuid, sourceId, opType, elfUuid, elfId, elfCnt, elfLv, elfStar",300)
+
 end
 init()
 

+ 18 - 0
script/common/LogDefine.lua

@@ -260,6 +260,17 @@ DEFINE = {
 	BusOneBuy				= 264,			 -- 新商业活动1-超值大礼
 	BusOneYuanZheng			= 265,			 -- 新商业活动1-远征豪礼
 	BusOneHeroYuanZheng		= 266,			 -- 新商业活动1-英雄远征
+	BusThreeTask			= 267,			 -- 新商业活动3-任务
+	BusThreeGrandGift		= 268,			 -- 新商业活动3-超值豪礼
+	BusThreeActDice			= 269,			 -- 新商业活动3-掷骰子
+	BusThreeDiscountStore	= 270,			 -- 新商业活动3-特价商店
+	CommonActBoss			= 271,			 -- 通用节日活动-个人BOSS
+	CommonActShop			= 272,			 -- 通用节日活动-节日商店
+	CommonActCharge			= 273,			 -- 通用节日活动-节日累充
+	CommonActFindTreasure	= 274,			 -- 通用节日活动-限时寻宝
+	UnlimitDrawCard			= 275,			 -- 无限高抽
+	OpenServerGiftPackage   = 276,			 -- 开服礼包
+	item_hecheng  			= 277,			 -- 物品合成
 
 	abs_totalReach          = 500,           -- 周期性活动累计
     abs_singleReach         = 501,           -- 周期性活动单次
@@ -296,6 +307,13 @@ DEFINE = {
 	cycleAct_breakThrough	= 770,			-- 新商业化活动2 —— 6元闯关
 	cycleAct_makeFood		= 771,			-- 新商业化活动2 —— 烹饪嘉年华
 	HeroPub					= 772,			-- 英雄酒馆
+	HeroSeed				= 773,			-- 英雄种子
+	zhuanpanGift			= 774,			-- 寻星礼包
+	elfUpGradeLv			= 775,			-- 精灵升级
+	elfUpGradeStar			= 776,			-- 精灵升星
+
+
+	errHandle				= 99999,		-- 异常处理
 }
 
 

+ 90 - 15
script/common/ProtoID.lua

@@ -1584,20 +1584,20 @@ _ENV[1627]="GC_CYCLMAKEFOOD_QUERY"
 _ENV[1628]="CG_CYCLMAKEFOOD_MAKEFOOD"
 _ENV[1629]="GC_CYCLMAKEFOOD_MAKEFOOD"
 
--- _ENV[1630]="CG_NEW_BUSTHREEACT_TASKQUERY"
--- _ENV[1631]="GC_NEW_BUSTHREEACT_TASKQUERY"
--- _ENV[1632]="CG_NEW_BUSTHREEACT_GETTASKPRIZE"
--- _ENV[1633]="CG_NEW_BUSTHREEACT_TASKPOINTQUERY"
--- _ENV[1634]="GC_NEW_BUSTHREEACT_TASKPOINTQUERY"
--- _ENV[1635]="CG_NEW_BUSTHREEACT_GETTASKPOINTPRIZE"
--- _ENV[1636]="GC_NEW_BUSTHREEACT_DISQUERY"
--- _ENV[1637]="GC_NEW_BUSTHREEACT_DISQUERY"
--- _ENV[1638]="CG_NEW_BUSTHREEACT_DISBUY"
--- _ENV[1639]="CG_NEW_BUSTHREEACT_GRANDGIFT_QUERY"
--- _ENV[1640]="GC_NEW_BUSTHREEACT_GRANDGIFT_QUERY"
--- _ENV[1641]="CG_NEW_BUSTHREEACT_GRANDGIFT_GET"
--- _ENV[1642]="CG_NEW_BUSTHREEACT_DICEDO"
--- _ENV[1643]="GC_NEW_BUSTHREEACT_DICEDO"
+_ENV[1630]="CG_NEW_BUSTHREEACT_TASKQUERY"
+_ENV[1631]="GC_NEW_BUSTHREEACT_TASKQUERY"
+_ENV[1632]="CG_NEW_BUSTHREEACT_GETTASKPRIZE"
+_ENV[1633]="CG_NEW_BUSTHREEACT_TASKPOINTQUERY"
+_ENV[1634]="GC_NEW_BUSTHREEACT_TASKPOINTQUERY"
+_ENV[1635]="CG_NEW_BUSTHREEACT_GETTASKPOINTPRIZE"
+_ENV[1636]="CG_NEW_BUSTHREEACT_DISQUERY"
+_ENV[1637]="GC_NEW_BUSTHREEACT_DISQUERY"
+_ENV[1638]="CG_NEW_BUSTHREEACT_DISBUY"
+_ENV[1639]="CG_NEW_BUSTHREEACT_GRANDGIFT_QUERY"
+_ENV[1640]="GC_NEW_BUSTHREEACT_GRANDGIFT_QUERY"
+_ENV[1641]="CG_NEW_BUSTHREEACT_GRANDGIFT_GET"
+_ENV[1642]="CG_NEW_BUSTHREEACT_DICEDO"
+_ENV[1643]="GC_NEW_BUSTHREEACT_DICEDO"
 
 _ENV[1644]="CG_SHOP_CHOSE_ITEM"
 _ENV[1645]="CG_BUY_LIFTTIME_CARD"
@@ -1612,4 +1612,79 @@ _ENV[1652]="CG_HEROPUB_REWARD_GET"
 
 _ENV[1653]="CG_HUNAGJINGTOWER_ONECLICK_SAPDANG"
 
-_ENV[1654]="GC_HEROPUB_BOX_REDDOT"
+_ENV[1654]="GC_HEROPUB_BOX_REDDOT"
+
+_ENV[1655]="CG_ABS_FESTIVAL_BOSS_QUERY"
+_ENV[1656]="GC_ABS_FESTIVAL_BOSS_QUERY"
+_ENV[1657]="CG_ABS_FESTIVAL_BOSS_REWARD"
+_ENV[1658]="GC_ABS_FESTIVAL_BOSS_REWARD"
+_ENV[1659]="CG_ABS_FESTIVAL_SHOP_QUERY"
+_ENV[1660]="GC_ABS_FESTIVAL_SHOP_QUERY"
+_ENV[1661]="CG_ABS_FESTIVAL_SHOP_BUY"
+_ENV[1662]="CG_ABS_FESTIVAL_RECHARGE_QUERY"
+_ENV[1663]="GC_ABS_FESTIVAL_RECHARGE_QUERY"
+_ENV[1664]="CG_ABS_FESTIVAL_RECHARGE_GET"
+_ENV[1665]="CG_ABS_FESTIVAL_SEVENDAY_CARD_QUERY"
+_ENV[1666]="GC_ABS_FESTIVAL_SEVENDAY_CARD_QUERY"
+_ENV[1667]="CG_ABS_FESTIVAL_SEVENDAY_CARD_DO"
+_ENV[1668]="CG_ABS_FESTIVAL_BOSS_GET"
+
+_ENV[1672]="CG_AREABATTLE_BASEINFO_QUERY"
+_ENV[1673]="GC_AREABATTLE_BASEINFO_QUERY"
+_ENV[1674]="CG_AREABATTLE_JOINPLAYER_QUERY"
+_ENV[1675]="GC_AREABATTLE_JOINPLAYER_QUERY"
+_ENV[1676]="CG_AREABATTLE_MATCHLIST_QUERY"
+_ENV[1677]="GC_AREABATTLE_MATCHLIST_QUERY"
+_ENV[1678]="CG_AREABATTLE_COMBATVIDEO_QUERY"
+_ENV[1679]="GC_AREABATTLE_COMBATVIDEO_QUERY"
+_ENV[1680]="CG_AREABATTLE_REWARD_QUERY"
+_ENV[1681]="GC_AREABATTLE_REWARD_QUERY"
+
+_ENV[1682]="GC_SKIN_DATA_QUERY"
+
+_ENV[1683]="CG_UNLIMITDRAW_QUERY"
+_ENV[1684]="GC_UNLIMITDRAW_QUERY"
+_ENV[1685]="CG_UNLIMITDRAW_DO"
+_ENV[1686]="GC_UNLIMITDRAW_DO"
+_ENV[1687]="CG_UNLIMITDRAW_ABANDON"
+_ENV[1688]="CG_UNLIMITDRAW_GET"
+
+_ENV[1689]="CG_COMMON_HUMAN_INFO"       -- 玩家通用的一些数据请求(是否首充等)
+_ENV[1690]="GC_COMMON_HUMAN_INFO"
+
+_ENV[1691]="CG_HEROSEED_QUERY_ALL"
+_ENV[1692]="GC_HEROSEED_QUERY_ALL"
+_ENV[1693]="CG_HEROSEED_QUERY_SINGLE"
+_ENV[1694]="GC_HEROSEED_QUERY_SINGLE"
+_ENV[1695]="CG_HEROSEED_UPGRADE"
+
+_ENV[1697]="CG_OPENSERVER_GIFTPACKAGE_QUERY"
+_ENV[1698]="GC_OPENSERVER_GIFTPACKAGE_QUERY"
+
+_ENV[1699]="CG_ZHUANPAN_GIFT_QUERY"
+_ENV[1700]="GC_ZHUANPAN_GIFT_QUERY"
+
+_ENV[1701]="CG_DUIHUANG_QUERY"
+_ENV[1702]="GC_DUIHUANG_QUERY"
+_ENV[1703]="CG_DUIHUANG_DO"
+_ENV[1704]="GC_EQUIP_REFINING_QUERY"
+_ENV[1705]="CG_EQUIP_REFINING_DO"
+_ENV[1706]="GC_EQUIP_REFINING_DO"
+_ENV[1707]="CG_EQUIP_REFINING_ABANDON"
+_ENV[1708]="CG_EQUIP_REFINING_SAVE"
+_ENV[1709]="CG_EQUIP_REFINING_QUERY"
+
+_ENV[1710]="CG_CYCLMAKEFOOD_SELECT_MUL"
+_ENV[1711]="GC_ITEM_BAG_LIST_CHANGE"
+
+_ENV[1712]="CG_ELF_SIMPLEDATA_QUERY"
+_ENV[1713]="GC_ELF_SIMPLEDATA_QUERY"
+_ENV[1714]="CG_ELF_SINGLE_QUERY"
+_ENV[1715]="GC_ELF_SINGLE_QUERY"
+_ENV[1716]="CG_ELF_UPGRADE_LV"
+_ENV[1717]="CG_ELF_UPGRADE_STAR"
+_ENV[1718]="CG_ELF_POS_QUERY"
+_ENV[1719]="GC_ELF_POS_QUERY"
+_ENV[1720]="CG_COMBAT_ELFPOS_QUERY"
+_ENV[1721]="GC_COMBAT_ELFPOS_QUERY"
+_ENV[1722]="CG_COMBAT_ELFPOS_DO"

+ 8 - 0
script/common/Util.lua

@@ -392,6 +392,14 @@ function getWeekDay( time )
 	return d.wday
 end
 
+-- 处于第几分钟
+function getMin(time)
+	time = time or os.time()
+	local d = os.date("*t",time)
+	return d.min
+end
+
+
 function split(str, split_char,isNumber)
     local t = {}
     while string.len(str)>0 do

+ 1 - 1
script/core/DataCache.lua

@@ -7,7 +7,7 @@ local Util = require("common.Util")
 
 
 -- 开服第10天以后才缓存玩家uid
-local CACHE_UUID_STARTDAY = 10
+local CACHE_UUID_STARTDAY = 1  --10, 改为开服就缓存
 
 
 local player_uuid_list = {}

+ 1 - 0
script/core/ObjHuman.lua

@@ -484,6 +484,7 @@ function onLvUpCB(human, oldLv, newLv)
 	local DataCache = require("core.DataCache")
 	DataCache.Update_PlayerLv(human.db._id, human.db.lv)
 
+	commonOperate.LvChange(human, oldLv, newLv)
 
 	--升级日志
 	--Log.write(Log.LOGID_OSS_LEVELUP, human.db._id, human.db.account, human.db.name, oldLv, newLv)

+ 1 - 1
script/core/RoleDel.lua

@@ -7,12 +7,12 @@ local Log = require("common.Log")
 local LogDefine = require("common.LogDefine")
 local DataCache = require("core.DataCache")
 
+
 local RoleList = {}
 local function delRoles()
     _G.collectgarbage("step", 1000000)
 
 	local player_uuid_list = {}
-
 	LuaMongo.find(DB.db_char, nil, {lastLoginTime = 1, lastLogoutTime = 1, lv = 1, zuanshi = 1, buy = 1, account = 1})
 	local list = {}
 	RoleList = {}

+ 3 - 3
script/core/Timer.lua

@@ -48,7 +48,7 @@ local JjcNewLadderLogic = require("jjcnewladder.jjcNewLadderLogic")
 local CycleActivityLogic = require("yunying.CycleActivity")
 local commonOperate = require("core.commonOperate")
 local GodsAreaCS = require("godsArea.GodsAreaCS")
-
+local AreaBattleCS = require("areaBattle.AreaBattleCS")
 
 register_timer = {    
 	monitor = 60000,            -- 
@@ -88,8 +88,7 @@ function oneMin()
     MiddleConnect.onTimer()
     ZhanbuLogic.checkRecover()
 
-    -- 测试
-    GodsAreaCS.oneMin()
+    AreaBattleCS.oneMin()
 end
 
 function offlineCheck()
@@ -134,6 +133,7 @@ function doZhengDian(hour)
     end
 
     GodsAreaCS.onHour(hour)
+    AreaBattleCS.onHour(hour)
     --if hour == 21 then
     --    if _G.is_middle ~= true then 
     --        JjcLogic.onHour(hour)

+ 14 - 0
script/core/commonOperate.lua

@@ -1,5 +1,7 @@
 local Util = require("common.Util")
 local OneKillGiftLogic = require("present.OneKillGift")
+local WarOrder = require("shop.WarOrder")
+local UnlimitDrawLogic = require("drawCard.UnlimitDrawLogic")
 
 function onZero()
     OneKillGiftLogic.onZero()
@@ -7,4 +9,16 @@ end
 
 function onLogin(human)
     OneKillGiftLogic.onLogin(human)
+    UnlimitDrawLogic.onLogin(human)
+end
+
+function LvChange(human, nOldeLv, nNewLv)
+    if nOldeLv >= nNewLv then
+        return
+    end
+
+    local nCnt = nNewLv - nOldeLv
+    WarOrder.trigger(human, 6, nCnt) -- 等级战令
+
+    UnlimitDrawLogic.onLvUp(human, nNewLv)
 end

+ 2 - 1
script/excel/ssecy/combat.lua

@@ -24,7 +24,8 @@
 [25]={name="妖族试炼",mapID=2002,moduleFn="racialTrial.RacialTrialLogic",systemID=0,isQuickTime="10,2,3",isQuick=1,teamType=31,group=0,isAttack=1,panelIDs={1721},maxRound=17,isSkip=0,hpLimit=0,fightMode={},PVP=0},
 [26]={name="人族试炼",mapID=2002,moduleFn="racialTrial.RacialTrialLogic",systemID=0,isQuickTime="10,2,3",isQuick=1,teamType=32,group=0,isAttack=1,panelIDs={1722},maxRound=17,isSkip=0,hpLimit=0,fightMode={},PVP=0},
 [27]={name="兽族试炼",mapID=2002,moduleFn="racialTrial.RacialTrialLogic",systemID=0,isQuickTime="10,2,3",isQuick=1,teamType=33,group=0,isAttack=1,panelIDs={1723},maxRound=17,isSkip=0,hpLimit=0,fightMode={},PVP=0},
-[28]={name="仙魔试炼",mapID=2002,moduleFn="racialTrial.RacialTrialLogic",systemID=0,isQuickTime="10,2,3",isQuick=1,teamType=34,group=0,isAttack=1,panelIDs={1724},maxRound=17,isSkip=0,hpLimit=0,fightMode={},PVP=0}}end)();
+[28]={name="仙魔试炼",mapID=2002,moduleFn="racialTrial.RacialTrialLogic",systemID=0,isQuickTime="10,2,3",isQuick=1,teamType=34,group=0,isAttack=1,panelIDs={1724},maxRound=17,isSkip=0,hpLimit=0,fightMode={},PVP=0},
+[35]={name="调教英雄",mapID=1016,moduleFn="battle.BattleLogic",systemID=0,isQuickTime="10,1,1",isQuick=1,teamType=35,group=0,isAttack=1,panelIDs={},maxRound=33,isSkip=0,hpLimit=0,fightMode={},PVP=0}}end)();
 (function()gm={
 [1]={atk={{405009,4,340,13},{405007,2,340,13},{405006,6,340,13},{405005,7,340,13},{405004,9,340,13}},def={{305009,2,340,13},{305010,6,340,13},{305011,4,340,13},{305006,7,340,13},{305007,9,340,13}},atkF=1,defF=1,atkPet=0,defPet=0,items={}},
 [2]={atk={{505004,4,340,13},{505005,2,340,13},{505006,6,340,13},{505007,7,340,13},{505008,9,340,13}},def={{305009,2,340,13},{305010,6,340,13},{305011,4,340,13},{305006,7,340,13},{305007,9,340,13}},atkF=1,defF=1,atkPet=0,defPet=0,items={}},

+ 22 - 0
script/excel/ssecy/peakBattlefieldReward.lua

@@ -0,0 +1,22 @@
+-- 巅峰战场奖励配置表
+-- 奖励类型:1=挑战奖励,2=活动名次奖励,3=扩展排名奖励
+-- 奖励编号:1001=战胜,1002=战败,2001-2009=排名奖励
+-- rank字段:数组格式 [minRank, maxRank],挑战奖励可为空或[0,0]
+
+(function()rankReward={
+-- 挑战奖励(奖励类型=1)
+[1001]={rewardType=1,rewardID=1001,rank={0,0},reward={{101,10},{102,10}}},
+[1002]={rewardType=1,rewardID=1002,rank={0,0},reward={{101,1},{102,1}}},
+-- 活动名次奖励(奖励类型=2)
+[2001]={rewardType=2,rewardID=2001,rank={1,1},reward={{101,10},{102,10}}},
+[2002]={rewardType=2,rewardID=2002,rank={2,2},reward={{101,10},{102,10}}},
+[2003]={rewardType=2,rewardID=2003,rank={3,3},reward={{101,10},{102,10}}},
+[2004]={rewardType=2,rewardID=2004,rank={4,5},reward={{101,10},{102,10}}},
+[2005]={rewardType=2,rewardID=2005,rank={6,10},reward={{101,10},{102,10}}},
+[2006]={rewardType=2,rewardID=2006,rank={11,20},reward={{101,10},{102,10}}},
+[2007]={rewardType=2,rewardID=2007,rank={21,50},reward={{101,10},{102,10}}},
+[2008]={rewardType=2,rewardID=2008,rank={51,100},reward={{101,10},{102,10}}},
+-- 扩展排名奖励(奖励类型=3)
+[2009]={rewardType=3,rewardID=2009,rank={101,99999},reward={{101,10},{102,10}}}
+}end)();
+

+ 1 - 1
script/merge/MergeServerCS.lua

@@ -67,7 +67,7 @@ function AfterStart()
     end
 
     local updateTb, removeTb = generateArray()
-    if not next(updateTb) and not next(removeTb) then
+    if (not updateTb or not next(updateTb)) and (not removeTb or not next(removeTb)) then
         return
     end
 

+ 52 - 23
script/merge/MergeServerDefine.lua

@@ -73,6 +73,8 @@ CHANNEL_ID_SANLI_H5 = 5
 CHANNEL_ID_SANLI_4399 = 6
 CHANNEL_ID_SANLI_360 = 7
 
+CHANNEL_ID_SANLI_SHIYOU = 10
+
 -- 数据库名中字符串部分的格式
 DB_NAME_STR = "ckwy_fy_S"
 
@@ -93,6 +95,9 @@ CHANNEL_2_DBNUMBER = {
     -- 三狸H5,4399
     [CHANNEL_ID_SANLI_H5] = 550001,
     [CHANNEL_ID_SANLI_4399] = 550001,
+
+    -- 三狸视游
+    [CHANNEL_ID_SANLI_SHIYOU] = 750001,
 }
 
 -- 要进行合并的数据库所属渠道ID, 用于检测合错数据库的情况, 与下面的 MERGE_DB_TB 的值一一对应
@@ -100,40 +105,64 @@ CHANNEL_2_DBNUMBER = {
 MERGE_CHECK_TB = {
     -- 木子/Tap
     [CHANNEL_ID_TAP] = {
-        { {CHANNEL_ID_TAP, 21, 0},  {CHANNEL_ID_TAP, 22, 1} },
-        { {CHANNEL_ID_TAP, 23, 0},  {CHANNEL_ID_TAP, 24, 1} },
-        { {CHANNEL_ID_TAP, 25, 0},  {CHANNEL_ID_TAP, 26, 1} },
-        { {CHANNEL_ID_TAP, 27, 0},  {CHANNEL_ID_TAP, 28, 1} },
-        { {CHANNEL_ID_TAP, 29, 0},  {CHANNEL_ID_TAP, 30, 1} },
+        { {CHANNEL_ID_TAP, 71, 0},  {CHANNEL_ID_TAP, 72, 1} },
+        { {CHANNEL_ID_TAP, 73, 0},  {CHANNEL_ID_TAP, 74, 1} },
+        { {CHANNEL_ID_TAP, 75, 0},  {CHANNEL_ID_TAP, 76, 1} },
+        { {CHANNEL_ID_TAP, 77, 0},  {CHANNEL_ID_TAP, 78, 1} },
+        { {CHANNEL_ID_TAP, 79, 0},  {CHANNEL_ID_TAP, 80, 1} },
+        { {CHANNEL_ID_TAP, 81, 0},  {CHANNEL_ID_TAP, 82, 1} },
+        { {CHANNEL_ID_TAP, 83, 0},  {CHANNEL_ID_TAP, 84, 1} },
+        { {CHANNEL_ID_TAP, 85, 0},  {CHANNEL_ID_TAP, 86, 1} },
+        { {CHANNEL_ID_TAP, 87, 0},  {CHANNEL_ID_TAP, 88, 1} },
+        { {CHANNEL_ID_TAP, 89, 0},  {CHANNEL_ID_TAP, 90, 1} },
     },
 
     -- 三狸功夫
     [CHANNEL_ID_SANLI_ANDOIRD] = {
-        { {CHANNEL_ID_SANLI_ANDOIRD, 41, 0}, {CHANNEL_ID_SANLI_ANDOIRD, 42, 1}, {CHANNEL_ID_SANLI_H5, 31, 2}, {CHANNEL_ID_SANLI_H5, 32, 2} },
-        { {CHANNEL_ID_SANLI_ANDOIRD, 43, 0}, {CHANNEL_ID_SANLI_ANDOIRD, 44, 1}, {CHANNEL_ID_SANLI_H5, 33, 2}, {CHANNEL_ID_SANLI_H5, 34, 2} },
-        { {CHANNEL_ID_SANLI_ANDOIRD, 45, 0}, {CHANNEL_ID_SANLI_ANDOIRD, 46, 1}, {CHANNEL_ID_SANLI_H5, 35, 2}, {CHANNEL_ID_SANLI_H5, 36, 2} },
-        { {CHANNEL_ID_SANLI_ANDOIRD, 47, 0}, {CHANNEL_ID_SANLI_ANDOIRD, 48, 1}, {CHANNEL_ID_SANLI_H5, 37, 2}, {CHANNEL_ID_SANLI_H5, 38, 2} },
-        { {CHANNEL_ID_SANLI_ANDOIRD, 49, 0}, {CHANNEL_ID_SANLI_ANDOIRD, 50, 1}, {CHANNEL_ID_SANLI_H5, 39, 2}, {CHANNEL_ID_SANLI_H5, 40, 2} },
+        { {CHANNEL_ID_SANLI_ANDOIRD, 81, 0}, {CHANNEL_ID_SANLI_ANDOIRD, 82, 1} },
+        { {CHANNEL_ID_SANLI_ANDOIRD, 83, 0}, {CHANNEL_ID_SANLI_ANDOIRD, 84, 1} },
+        { {CHANNEL_ID_SANLI_ANDOIRD, 85, 0}, {CHANNEL_ID_SANLI_ANDOIRD, 86, 1} },
+        { {CHANNEL_ID_SANLI_ANDOIRD, 87, 0}, {CHANNEL_ID_SANLI_ANDOIRD, 88, 1} },
+        { {CHANNEL_ID_SANLI_ANDOIRD, 89, 0}, {CHANNEL_ID_SANLI_ANDOIRD, 90, 1} },
+        { {CHANNEL_ID_SANLI_ANDOIRD, 91, 0}, {CHANNEL_ID_SANLI_ANDOIRD, 92, 1} },
+        { {CHANNEL_ID_SANLI_ANDOIRD, 93, 0}, {CHANNEL_ID_SANLI_ANDOIRD, 94, 1} },
+        { {CHANNEL_ID_SANLI_ANDOIRD, 95, 0}, {CHANNEL_ID_SANLI_ANDOIRD, 96, 1} },
+        { {CHANNEL_ID_SANLI_ANDOIRD, 97, 0}, {CHANNEL_ID_SANLI_ANDOIRD, 98, 1} },
+        { {CHANNEL_ID_SANLI_ANDOIRD, 99, 0}, {CHANNEL_ID_SANLI_ANDOIRD, 100, 1} },
     },
 
 
     -- 三狸H5
-    [CHANNEL_ID_SANLI_H5] = {
-        { {CHANNEL_ID_SANLI_ANDOIRD, 41, 0},  {CHANNEL_ID_SANLI_H5, 31, 2}, {CHANNEL_ID_SANLI_H5, 32, 2} },
-        { {CHANNEL_ID_SANLI_ANDOIRD, 43, 0},  {CHANNEL_ID_SANLI_H5, 33, 2}, {CHANNEL_ID_SANLI_H5, 34, 2} },
-        { {CHANNEL_ID_SANLI_ANDOIRD, 45, 0},  {CHANNEL_ID_SANLI_H5, 35, 2}, {CHANNEL_ID_SANLI_H5, 36, 2} },
-        { {CHANNEL_ID_SANLI_ANDOIRD, 47, 0},  {CHANNEL_ID_SANLI_H5, 37, 2}, {CHANNEL_ID_SANLI_H5, 38, 2} },
-        { {CHANNEL_ID_SANLI_ANDOIRD, 49, 0},  {CHANNEL_ID_SANLI_H5, 39, 2}, {CHANNEL_ID_SANLI_H5, 40, 2} },
-    },
+    -- [CHANNEL_ID_SANLI_H5] = {
+    --     { {CHANNEL_ID_SANLI_ANDOIRD, 41, 0},  {CHANNEL_ID_SANLI_H5, 31, 2}, {CHANNEL_ID_SANLI_H5, 32, 2} },
+    --     { {CHANNEL_ID_SANLI_ANDOIRD, 43, 0},  {CHANNEL_ID_SANLI_H5, 33, 2}, {CHANNEL_ID_SANLI_H5, 34, 2} },
+    --     { {CHANNEL_ID_SANLI_ANDOIRD, 45, 0},  {CHANNEL_ID_SANLI_H5, 35, 2}, {CHANNEL_ID_SANLI_H5, 36, 2} },
+    --     { {CHANNEL_ID_SANLI_ANDOIRD, 47, 0},  {CHANNEL_ID_SANLI_H5, 37, 2}, {CHANNEL_ID_SANLI_H5, 38, 2} },
+    --     { {CHANNEL_ID_SANLI_ANDOIRD, 49, 0},  {CHANNEL_ID_SANLI_H5, 39, 2}, {CHANNEL_ID_SANLI_H5, 40, 2} },
+    -- },
 
 
     -- 三狸QQ
-    [CHANNEL_ID_SANLI_QQ] = {
-        { {CHANNEL_ID_SANLI_QQ, 21, 0},  {CHANNEL_ID_SANLI_QQ, 22, 1} },
-        { {CHANNEL_ID_SANLI_QQ, 23, 0},  {CHANNEL_ID_SANLI_QQ, 24, 1} },
-        { {CHANNEL_ID_SANLI_QQ, 25, 0},  {CHANNEL_ID_SANLI_QQ, 26, 1} },
-        { {CHANNEL_ID_SANLI_QQ, 27, 0},  {CHANNEL_ID_SANLI_QQ, 28, 1} },
-        { {CHANNEL_ID_SANLI_QQ, 29, 0},  {CHANNEL_ID_SANLI_QQ, 30, 1} },
+    -- [CHANNEL_ID_SANLI_QQ] = {
+    --     { {CHANNEL_ID_SANLI_QQ, 51, 0},  {CHANNEL_ID_SANLI_QQ, 52, 1} },
+    --     { {CHANNEL_ID_SANLI_QQ, 53, 0},  {CHANNEL_ID_SANLI_QQ, 54, 1} },
+    --     { {CHANNEL_ID_SANLI_QQ, 55, 0},  {CHANNEL_ID_SANLI_QQ, 56, 1} },
+    --     { {CHANNEL_ID_SANLI_QQ, 57, 0},  {CHANNEL_ID_SANLI_QQ, 58, 1} },
+    --     { {CHANNEL_ID_SANLI_QQ, 59, 0},  {CHANNEL_ID_SANLI_QQ, 60, 1} },
+    --     { {CHANNEL_ID_SANLI_QQ, 61, 0},  {CHANNEL_ID_SANLI_QQ, 62, 1} },
+    --     { {CHANNEL_ID_SANLI_QQ, 63, 0},  {CHANNEL_ID_SANLI_QQ, 64, 1} },
+    --     { {CHANNEL_ID_SANLI_QQ, 65, 0},  {CHANNEL_ID_SANLI_QQ, 66, 1} },
+    --     { {CHANNEL_ID_SANLI_QQ, 67, 0},  {CHANNEL_ID_SANLI_QQ, 68, 1} },
+    --     { {CHANNEL_ID_SANLI_QQ, 69, 0},  {CHANNEL_ID_SANLI_QQ, 70, 1} },
+    -- },
+
+    -- 三狸视游
+    [CHANNEL_ID_SANLI_SHIYOU] = {
+        { {CHANNEL_ID_SANLI_SHIYOU, 1, 0},  {CHANNEL_ID_SANLI_SHIYOU, 2, 1} },
+        { {CHANNEL_ID_SANLI_SHIYOU, 3, 0},  {CHANNEL_ID_SANLI_SHIYOU, 4, 1} },
+        { {CHANNEL_ID_SANLI_SHIYOU, 5, 0},  {CHANNEL_ID_SANLI_SHIYOU, 6, 1} },
+        { {CHANNEL_ID_SANLI_SHIYOU, 7, 0},  {CHANNEL_ID_SANLI_SHIYOU, 8, 1} },
+        { {CHANNEL_ID_SANLI_SHIYOU, 9, 0},  {CHANNEL_ID_SANLI_SHIYOU, 10, 1} },
     },
 
 }

+ 25 - 1
script/module/WeekendLoopActivity/WeekendLoopActCard.lua

@@ -219,7 +219,7 @@ local function WeekActCard_SetCardNum(human, nValue)
 
     local nNowCard = WeekActCard_GetCardNum(human)
     if -1 >= nNowCard then
-       WeekActCard_WriteLog(human, "[WeekActCard_SetCardNum]", "获取古玉数量失败")
+       WeekActCard_WriteLog(human, "[WeekActCard_SetCardNum]", "获取抽卡数量失败")
         return
     end
 
@@ -465,4 +465,28 @@ function WeekActCard_GetPrize(human)
 
     WeekActCard_Query(human)
     WeekendLoopActManger.WeekLoopACT_SendActInfo(human)
+end
+
+function onLogin(human)
+    if not human.db.nWeekCardNum or not human.db.tWeekCardPrize then
+        return
+    end
+
+    local nNowCard = WeekActCard_GetCardNum(human)
+    if -1 >= nNowCard then
+        return
+    end
+
+    local tConfig = WeekActCard_GetConfigByHuman(human)
+    if tConfig then
+        for nID, v in pairs(tConfig) do
+            local nStatus = WeekActCard_GetPrizeStatus(human, nID)
+            if nNowCard >= v.nNum and WeekLoopActDef.WEEKACT_STATE_NONE == nStatus then
+                local bRet = WeekActCard_SetPrizeStatus(human, nID, WeekLoopActDef.WEEKACT_STATE_CANGET)
+                if false == bRet then
+                    print("[WeekActCard_UseCard] 设置失败 nID = "..nID.." nStatus = "..nStatus.." num = "..v.nNum)
+                end
+            end
+        end
+    end
 end

+ 38 - 0
script/module/WeekendLoopActivity/WeekendLoopActHeroStar.lua

@@ -50,6 +50,20 @@ local function WeekActHeroStar_GetHeroID(human)
     return human.db.nWeekHeroID
 end
 
+-- 重置选择的英雄最大星数
+local function WeekActHeroStar_RestHeroStar(human)
+    human.db.nWeekHeroStar = 0
+end
+
+-- 设置当前英雄最大星数
+local function WeekActHeroStar_SetHeroStar(human, nStar)
+    human.db.nWeekHeroStar = math.max(human.db.nWeekHeroStar, nStar)
+end
+
+local function WeekActHeroStar_GetHeroStar(human)
+    return human.db.nWeekHeroStar
+end
+
 -- 设置英雄ID
 local function WeekActHeroStar_SetHeroID(human, nHeroID)
     if not human or not nHeroID then
@@ -58,6 +72,7 @@ local function WeekActHeroStar_SetHeroID(human, nHeroID)
     end
 
     human.db.nWeekHeroID = nHeroID
+    WeekActHeroStar_RestHeroStar(human)
 end
 
 -- 初始化奖励信息
@@ -176,6 +191,8 @@ function WeekActHeroStar_End(human)
     local senderName = tMailConfig.senderName
     MailManager.add(MailManager.SYSTEM, human.db._id, title, content, items, senderName)
 
+    WeekActHeroStar_RestHeroStar(human)
+
     print("[WeekActHeroStar_End] 英雄升星 活动结束处理完成")
 end
 
@@ -361,6 +378,27 @@ function WeekActHeroStar_HeroStarUp(human, nHeroID, nStar)
         end
     end
 
+    WeekActHeroStar_SetHeroStar(human, nStar)
     WeekActHeroStar_Query(human)
     WeekendLoopActManger.WeekLoopACT_SendActInfo(human)
+end
+
+function onLogin(human)
+    if not human.db.nWeekHeroID or not human.db.nWeekHeroStar or not human.db.tWeekHeroPrize then
+        return
+    end
+
+    -- local tConfig = WeekActHeroStar_GetConfig()
+    -- local nNowStar = WeekActHeroStar_GetHeroStar(human)
+    -- if tConfig then
+    --     for nID, v in pairs(tConfig) do
+    --         if nNowStar >= nID then
+    --             local nStatus = WeekActHeroStar_GetPrizeStatus(human, nID)
+    --             if WeekLoopActDef.WEEKACT_STATE_NONE == nStatus then
+    --                 WeekActHeroStar_SetPrizeStatus(human, nID, WeekLoopActDef.WEEKACT_STATE_CANGET)
+    --             end
+    --         end
+    --     end
+    -- end
+
 end

+ 2 - 1
script/module/WeekendLoopActivity/WeekendLoopActManager.lua

@@ -26,7 +26,6 @@ local YunYingLogic = require("yunying.YunYingLogic")
 local WeekLoopActGuYu = require("WeekendLoopActivity.WeekendLoopActUseGuYu")
 local weekLoopActCard = require("WeekendLoopActivity.WeekendLoopActCard")
 local weekLoopActRank = require("WeekendLoopActivity.WeekendLoopActRank")
-local CommonDB = require("common.CommonDB")
 
 -- 活动信息
 tWeekActInfo = nil
@@ -405,6 +404,8 @@ function onLogin(human, funcID)
     -- 下发活动基础数据
     if true == WeekLoopACT_IsRun() then
         WeekLoopACT_SendActInfo(human)
+        weekLoopActCard.onLogin(human)
+        WeekLoopActHeroStar.onLogin(human)
     end
 end
 

+ 12 - 2
script/module/absAct/Abs365CardLogic.lua

@@ -153,7 +153,7 @@ end
 
 
 -- 积分购买
-function abs365Card(human, id, buyConf, isFirst, cnt)
+function abs365Card(human, id, buyConf, isFirst, cnt, nBuyNum)
     local state, endTime, starTime = AbsActLogic.isStarted(human, id)
     if not state then return end
 
@@ -285,4 +285,14 @@ function IsBuyCard(human)
     end
 
     return human.db.absAct[ABS365CARDID].active and human.db.absAct[ABS365CARDID].active or 0
-end
+end
+
+-- function GetRemainNum(human, nBuyID)
+--     local bBuy = IsBuyCard(human)
+--     -- 未购买
+--     if 0 == bBuy then
+--         return 1
+--     else 
+--         return 0
+--     end
+-- end

+ 13 - 6
script/module/absAct/AbsActLogic.lua

@@ -157,6 +157,13 @@ end
 function isStarted(human, id)
 	local config = AbsActExcel.absActivity[id]
 	if not config then return end
+
+    local nNowOpenDay = CommonDB.getServerOpenDay()
+    if nNowOpenDay < config.openDay then
+        -- print("[isStarted] 当前活动未开启 进行额外判断 id = "..id.." nNowOpenDay = "..nNowOpenDay.." config.openDay = "..config.openDay)
+        return
+    end
+
     local _,realEndTime,realStartTime = transTime(config)
 	local now = os.time()
     if 0 == realEndTime or 0 == realStartTime then
@@ -455,12 +462,12 @@ function getLuckDraw(human,luckDraw,randomIndex,isAct,op)
 end
 
 function onHour(hour)
-    if hour == 23 then
-        AbsActBillboardLogic.sendBillboardReward()
-    end
-    if hour == 1 then
-        AbsActBillboardLogic.cleanBillBoardDB()
-    end
+    -- if hour == 23 then
+    --     AbsActBillboardLogic.sendBillboardReward()
+    -- end
+    -- if hour == 1 then
+    --     AbsActBillboardLogic.cleanBillBoardDB()
+    -- end
 end
 
 function updateBillBoard(humanDb)

+ 25 - 1
script/module/absAct/AbsExcellentGiftLogic.lua

@@ -511,4 +511,28 @@ function FinishTaskByDiamond(human, id, taskIdx, page)
 
     --更新
     Query(human, id, page)
-end
+end
+
+-- function GetRemainNum(human, nBuyID)
+--     local actData = human.db.absAct[ACTID]
+--     if not actData or not actData.recordData then
+--         return 1
+--     end
+
+--     local ids = getTaskIdVec(nil, nBuyID)
+--     local config = AbsActExcel.AbsExcellentGiftLogic
+
+--     for _, id in ipairs(ids) do
+--         if not actData.recordData[id]  then
+--             return 1
+--         else 
+--             local singleCfg = config[id]
+--             local needBuyId = singleCfg.buyId
+--             if not actData.recordData[id][needBuyId] then
+--                 return 1
+--             else
+--                 return 0
+--             end
+--         end
+--     end
+-- end

+ 12 - 2
script/module/absAct/AbsWeeklyCardLogic.lua

@@ -29,6 +29,7 @@ local MailManager = require("mail.MailManager")
 local BagLogic = require("bag.BagLogic")
 
 DAY_CNT = 7
+local nABSWEEKLYCARDID = 12001
 
 local function initDB(human, id, actId)
     if not human.db.absAct[id] then return end
@@ -151,7 +152,7 @@ function updateDaily(human, id, findActId)
 end
 
 -- 礼包激活
-function absWeeklyCard(human, id, buyConf, isFirst, cnt)
+function absWeeklyCard(human, id, buyConf, isFirst, cnt, nBuyNum)
     local state, endTime, starTime = AbsActLogic.isStarted(human, id)
     if not state then return end
 
@@ -178,4 +179,13 @@ function absWeeklyCard(human, id, buyConf, isFirst, cnt)
 
     Broadcast.sendErr(human, Lang.ITEM_BUY_SUCCESS)
     getAndSendMsg(human, id, config)
-end
+end
+
+-- function GetRemainNum(human, nBuyID)
+--     local absAct = human.db.absAct[nABSWEEKLYCARDID]
+--     if not absAct then
+--         return 0
+--     else 
+--         return 1
+--     end
+-- end

+ 17 - 2
script/module/absAct/BusOneActivityBuy.lua

@@ -192,7 +192,7 @@ function isRed(human, YYInfo, absActConfig)
     return false
 end
 
-function onCharge(human, price, funcID, buyID)
+function onCharge(human, price, funcID, buyID, buyNum)
     print("[BusOneActivityBuy_onCharge] 进入购买 buyID = "..buyID)
     local bRed = false
     for nID, v in pairs(tBuyConf) do
@@ -212,4 +212,19 @@ function onCharge(human, price, funcID, buyID)
         YunYingLogic.sendBanner(human)
         BusOneActivityTask.BusOneTask_SendRed(human)
     end
-end
+end
+
+-- function GetRemainNum(human, nBuyID)
+--     for nID, v in pairs(tBuyConf) do
+--         if nBuyID == v.nBuyID then
+--             local nBuyNum = BusOneBuy_GetBuyNum(human, nID)
+--             if v.nBuyNum > nBuyNum then
+--                 return 1
+--             else
+--                 return 0
+--             end
+--         end
+--     end
+
+--     return 0
+-- end

+ 16 - 1
script/module/absAct/BusOneActivityYuanZheng.lua

@@ -269,4 +269,19 @@ function BusOneYuanZheng_NumChange(human, nNum)
         YunYingLogic.sendBanner(human)
         BusOneActivityTask.BusOneTask_SendRed(human)
     end
-end
+end
+
+-- function GetRemainNum(human, nBuyID)
+--     for nID, v in ipairs(tYuanZhengConf) do
+--         if v.nBuyID == nBuyID then
+--             local nPayStatus = BusOneYuanZheng_GetPayStatus(human, nID)
+--             if BUSONEYUANZHENG_PAY_NOGET == nPayStatus or BUSONEYUANZHENG_PAY_HUOYUE == nPayStatus then
+--                 return 1
+--             else
+--                 return 0
+--             end
+--         end
+--     end
+
+--     return 0
+-- end

+ 199 - 0
script/module/absAct/BusThreeActDice.lua

@@ -0,0 +1,199 @@
+--------------------------------
+-- 文件名       :   BusThreeActDice.lua
+-- 文件说明     :   新商业活动3-天选骰子
+-- 创建时间     :   2025/09/02
+-- 创建人       :   FC
+--------------------------------
+
+
+local tDiceConf = require("excel.BusThreeActivity").Dice
+local Util = require("common.Util")
+local Msg = require("core.Msg")
+local Grid = require("bag.Grid")
+local BagLogic = require("bag.BagLogic")
+local CommonDefine = require("common.CommonDefine")
+local AbsActLogic = require("absAct.AbsActLogic")
+local BuyLogic = require("topup.BuyLogic")
+local YunYingLogic = require("yunying.YunYingLogic")
+local BusActGrandGift = require("absAct.BusThreeActGrandGift")
+
+local BUSTHREEDICEABSID = 7404        -- 对应ABS活动ID
+-- 骰子类型
+local BUSDICE_TYPE_1 = 1              -- 数字全相同
+local BUSDICE_TYPE_2 = 2              -- 数字连续
+local BUSDICE_TYPE_3 = 3              -- 任意2个数字相同
+local BUSDICE_TYPE_4 = 4              -- 剩余情况
+
+local BUSDICE_GOODID = 1041          -- 物品ID
+
+local typeFuncMap = nil
+
+----------------------------------------- 内部处理开始 -------------------------------------
+local function BusThreeActDice_InitTypeFuncMap()
+    typeFuncMap = {
+        [BUSDICE_TYPE_1] = function (nPoint)
+            return nPoint.."|"..nPoint.."|"..nPoint
+        end,
+        [BUSDICE_TYPE_2] = function (nPoint)
+            local nRandNum = math.random(1, 6)
+            if nRandNum == 1 then
+                return nRandNum.."|"..(nRandNum+1).."|"..(nRandNum+2)
+            elseif nRandNum == 6 then
+                return (nRandNum-2).."|"..(nRandNum-1).."|"..nRandNum
+            else
+               return (nRandNum-1).."|"..nRandNum.."|"..(nRandNum+1)
+            end
+        end,
+        [BUSDICE_TYPE_3] = function (nPoint)
+            local nRandNum = math.random(1, 6)
+            local nOtherNum = nRandNum
+            local nDoLen = 0
+            while nOtherNum == nRandNum do
+                nOtherNum = math.random(1, 6)
+                nDoLen = nDoLen + 1
+                if nDoLen > 10 then
+                    break
+                end
+            end
+
+            if nRandNum == nOtherNum then
+                local nDifNum = math.random(1, 2)
+                nOtherNum = nDifNum == 1 and nRandNum - 1 or nRandNum + 1
+            end
+
+            local tPoint = {nRandNum, nRandNum, nOtherNum}
+            table.sort(tPoint)
+            return table.concat(tPoint, "|")
+        end,
+        [BUSDICE_TYPE_4] = function (nPoint)
+            local tPoint = {}
+            while #tPoint < 3 do
+                local nRandNum = math.random(1, 6)
+                local bExist = false
+                for _, v in ipairs(tPoint) do
+                    if v == nRandNum then
+                        bExist = true
+                        break
+                    end
+                end
+
+                if not bExist then
+                    table.insert(tPoint, nRandNum)
+                end
+            end
+
+            table.sort(tPoint)
+            -- 连续判断
+            if tPoint[1] + 1 == tPoint[2] and tPoint[2] + 1 == tPoint[3] then
+                if tPoint[1] > 1 then
+                    tPoint[1] = tPoint[1] - 1
+                else
+                    tPoint[3] = tPoint[3] + 1
+                end
+            end
+            return table.concat(tPoint, "|")
+        end,
+    }
+end
+
+-- 根据类型获取对应的随机点数
+local function BusThreeGrandGift_GetPoint(nType, nAppointPoint)
+    if not typeFuncMap then
+        BusThreeActDice_InitTypeFuncMap()
+    end
+
+    if not typeFuncMap or not typeFuncMap[nType] then
+        return false, nil
+    end
+
+    local func = typeFuncMap[nType]
+    return true, func(nAppointPoint)
+end
+
+local function BusThreeActDice_DiceDo(human, tMsgData, nNum)
+    local nAllWeight = 0
+    local tPrizeData = {}
+    for _, v in ipairs(tDiceConf) do
+        nAllWeight = nAllWeight + v.nWeight
+        table.insert(tPrizeData, {nWeight = nAllWeight, tPrize = v.Prize, nType = v.nType, nPoint = v.nPoint})
+    end
+
+    
+    local tItemList  = {}
+    tMsgData.tPrize[0] = nNum
+    for i = 1, nNum, 1 do
+        local tOneDiceData = tMsgData.tPrize[i]
+        local nRandWeight = math.random(1, nAllWeight)
+        local tChoseData = nil
+        for _, v in ipairs(tPrizeData) do
+            if nRandWeight <= v.nWeight then
+                tChoseData = v
+                break
+            end
+        end
+
+        if not tChoseData then
+            return false
+        end
+
+        local bRet = false
+        bRet, tOneDiceData.tPoint = BusThreeGrandGift_GetPoint(tChoseData.nType, tChoseData.nPoint)
+        if false == bRet then
+            print("[BusThreeActDice_DiceDo] 获取点数失败")
+            return false
+        end
+
+        -- print("[BusThreeActDice_DiceDo] 第 "..i.." 次 nType = "..tChoseData.nType.." nPoint = "..tChoseData.nPoint)
+        -- table.print_lua_table(tChoseData.tPrize)
+
+        tOneDiceData.titemData[0] = #tChoseData.tPrize
+        for j, v in ipairs(tChoseData.tPrize) do
+            Grid.makeItem(tOneDiceData.titemData[j], v[1], v[2])
+            if not tItemList[v[1]] then
+                tItemList[v[1]] = 0
+            end
+
+            tItemList[v[1]] = tItemList[v[1]] + v[2]
+        end
+
+        -- print("[BusThreeActDice_DiceDo] 第"..i.."次掷骰子结果: "..tOneDiceData.tPoint)
+    end
+
+    for nGoodID, nGoodNum in pairs(tItemList) do
+        BagLogic.addItem(human, nGoodID, nGoodNum, "BusThreeActDice")
+    end
+
+    return true
+end
+
+
+----------------------------------------- 客户端请求 -------------------------------------
+function BusThreeActDice_DO(human, nNum)
+    if 1 ~= nNum and 10 ~= nNum then
+        return
+    end
+
+    print("[BusThreeActDice_DO] 进行抽取 nNum = "..nNum)
+
+    local nGoodsNum = BagLogic.getItemCnt(human, BUSDICE_GOODID)
+    if nGoodsNum < nNum then
+        return
+    end
+
+    print("[BusThreeActDice_DO] 物品数量足够 nGoodsNum = "..nGoodsNum)
+
+    local tMsgData = Msg.gc.GC_NEW_BUSTHREEACT_DICEDO
+    local bRet = BusThreeActDice_DiceDo(human, tMsgData, nNum)
+    if not bRet then
+        print("[BusThreeActDice_DO] 进行抽取报错")
+        return
+    end
+
+    BagLogic.delItem(human, BUSDICE_GOODID, nNum, "BusThreeActDice")
+
+    BusActGrandGift.BusThreeGrandGift_NumChange(human, nNum)
+    print("[BusThreeActDice_DO] 物品扣除完成 nGoodsNum = "..nNum)
+    Msg.send(tMsgData, human.fd)
+    print("[BusThreeActDice_DO] 发送协议完成")
+end
+

+ 146 - 0
script/module/absAct/BusThreeActDiscountStore.lua

@@ -0,0 +1,146 @@
+--新商业化活动3—天选兑换
+--db
+--[=[
+    human.db.absAct[id] = {
+        buyRecord = {
+            [1] = 2, --key是道具在配置中的id, value是已经购买次数
+            [2] = 1,
+        }
+    }
+]=]--
+
+local Msg = require("core.Msg")
+local Grid = require("bag.Grid")
+local BagLogic = require("bag.BagLogic")
+local AbsActLogic = require("absAct.AbsActLogic")
+local Broadcast = require("broadcast.Broadcast")
+local Lang = require("common.Lang")
+local Config = require("excel.BusThreeActivity").DiscountStore
+
+local LOGTAG = "BusThreeDiscountStore" --日志标识
+
+local BUSTHREDISCOUNTSTOREABSID = 7403        -- 对应ABS活动ID
+
+local function CreateDB(human)
+    if not human.db.absAct[BUSTHREDISCOUNTSTOREABSID] then
+        human.db.absAct[BUSTHREDISCOUNTSTOREABSID] = {}
+    end
+
+    if not human.db.absAct[BUSTHREDISCOUNTSTOREABSID].buyRecord then
+        human.db.absAct[BUSTHREDISCOUNTSTOREABSID].buyRecord = {}
+    end
+
+    for index, v in ipairs(Config) do
+        human.db.absAct[BUSTHREDISCOUNTSTOREABSID].buyRecord[index] = 0
+    end
+end
+
+local function CheckAndCreateDB(human)
+    if not human.db.absAct[BUSTHREDISCOUNTSTOREABSID] or not human.db.absAct[BUSTHREDISCOUNTSTOREABSID].buyRecord then
+        CreateDB(human)
+    end
+end
+
+function isOpen(human, YYInfo, funcConfig)
+    local state, endTime, startTime = AbsActLogic.isStarted(human, funcConfig.funcID and funcConfig.funcID or BUSTHREDISCOUNTSTOREABSID)
+
+    return state, endTime, startTime
+end
+
+function isActive(human, YYInfo, funcConfig)
+    local state = isOpen(human, YYInfo, funcConfig)
+    return not state
+end
+
+-- function isRed(human, YYInfo, absActConfig)
+--     local state = AbsActLogic.isStarted(human, BUSTHREDISCOUNTSTOREABSID)
+--     if not state  then
+--         return false
+--     end
+
+--     CheckAndCreateDB(human)
+
+--     for nID, v in ipairs(Config) do
+        
+--         return true
+--     end
+
+--     return false
+-- end
+
+
+--查询
+function Query(human, id, isBuy)
+    CheckAndCreateDB(human)
+
+    local state = AbsActLogic.isStarted(human, BUSTHREDISCOUNTSTOREABSID)
+    if not state then
+        return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
+    end
+
+    local actData = human.db.absAct[BUSTHREDISCOUNTSTOREABSID]
+    if not actData then
+        return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
+    end
+
+    local buyRecord = actData.buyRecord
+    local msgRet = Msg.gc.GC_NEW_BUSTHREEACT_DISQUERY
+
+    local itemVec = msgRet.titemData
+    itemVec[0] = #Config
+
+    for k,v in ipairs(Config) do
+        local singleItem = itemVec[k]
+        singleItem.idx = k
+        singleItem.maxBuyCnt = v.maxBuyCnt
+        singleItem.nowBuyCnt = buyRecord and buyRecord[k] or 0
+        Grid.makeItem(singleItem.item, v.item[1], v.item[2])
+        Grid.makeItem(singleItem.currencyInfo, v.currencyInfo[1], v.currencyInfo[2])
+    end
+
+    Msg.send(msgRet, human.fd)
+end
+
+--购买商品
+function BuyItem(human, id, itemIdx, buyCnt)
+    local state = AbsActLogic.isStarted(human, id)
+    if not state then
+        return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
+    end
+
+    local actData = human.db.absAct[BUSTHREDISCOUNTSTOREABSID]
+    if not actData then
+        return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
+    end
+
+    local itemCfg = Config[itemIdx]
+    if not itemCfg or buyCnt <= 0 then
+        return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
+    end
+
+    local buyRecord = actData.buyRecord
+    if buyRecord and buyRecord[itemIdx] then
+        if buyRecord[itemIdx] + buyCnt > itemCfg.maxBuyCnt then
+            return Broadcast.sendErr(human, Lang.COMMON_BUY_NUM_NOT_ENOUGH)
+        end
+    end
+
+    local currencyInfo = itemCfg.currencyInfo
+    local cnt = currencyInfo[2] * buyCnt
+    if BagLogic.getItemCnt(human, currencyInfo[1]) < cnt then
+        return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
+    end
+    BagLogic.delItem(human, currencyInfo[1], cnt, LOGTAG)
+
+    --更新数据
+    buyRecord = buyRecord or {}
+    buyRecord[itemIdx] = (buyRecord[itemIdx] or 0) + buyCnt
+    actData.buyRecord = buyRecord
+
+    --发放奖励
+    local itemInfo = itemCfg.item
+    BagLogic.addItemList(human, {{itemInfo[1], itemInfo[2] * buyCnt}}, LOGTAG)
+
+    --下发数据
+    Query(human, id, true)
+end

+ 286 - 0
script/module/absAct/BusThreeActGrandGift.lua

@@ -0,0 +1,286 @@
+--------------------------------
+-- 文件名       :   BusThreeActGrandGift.lua
+-- 文件说明     :   新商业活动3-天选豪礼
+-- 创建时间     :   2025/09/01
+-- 创建人       :   FC
+--------------------------------
+
+local tGrandGiftConf = require("excel.BusThreeActivity").GrandGift
+local Util = require("common.Util")
+local Msg = require("core.Msg")
+local Grid = require("bag.Grid")
+local BagLogic = require("bag.BagLogic")
+local CommonDefine = require("common.CommonDefine")
+local AbsActLogic = require("absAct.AbsActLogic")
+local BuyLogic = require("topup.BuyLogic")
+local YunYingLogic = require("yunying.YunYingLogic")
+local AbsActExcel = require("excel.absAct")
+
+
+local BUSTHREEGRANDGIFTABSID = 7402        -- 对应ABS活动ID
+
+local BUSTHREEGRANDGIFT_PAY_NOGET = 0     -- 不可领取
+local BUSTHREEGRANDGIFT_PAY_BUY = 1       -- 已购买
+local BUSTHREEGRANDGIFT_PAY_HUOYUE = 2    -- 活跃度到达要求
+local BUSTHREEGRANDGIFT_PAY_CANGET = 3    -- 可以领取
+local BUSTHREEGRANDGIFT_PAY_GET = 4       -- 已领取
+
+----------------------------------------- 内部处理开始 -------------------------------------
+-- 创建DB
+local function BusThreeGrandGift_CreatDB(human)
+    if not human.db.absAct[BUSTHREEGRANDGIFTABSID] then
+        human.db.absAct[BUSTHREEGRANDGIFTABSID] = {}
+    end
+
+    human.db.absAct[BUSTHREEGRANDGIFTABSID].tGiftInfo = {
+        nNum = 0,
+        tStatus = {}
+    }
+
+    local tStatus = human.db.absAct[BUSTHREEGRANDGIFTABSID].tGiftInfo.tStatus
+    for nID, v in ipairs(tGrandGiftConf) do
+        tStatus[nID] = {
+            nFreeStatus = CommonDefine.COMMON_PRIZE_STATE_NOGET,
+            nPayStatus = BUSTHREEGRANDGIFT_PAY_NOGET
+        }
+    end
+end
+
+-- 重置DB
+local function BusThreeGrandGift_CheckAndResetDB(human)
+    if not human.db.absAct[BUSTHREEGRANDGIFTABSID] or nil == _G.next(human.db.absAct[BUSTHREEGRANDGIFTABSID]) 
+        or not human.db.absAct[BUSTHREEGRANDGIFTABSID].tGiftInfo then
+        BusThreeGrandGift_CreatDB(human)
+    end
+end
+
+-- 获取当前远征次数
+local function BusThreeGrandGift_GetBuyNum(human)
+    return human.db.absAct[BUSTHREEGRANDGIFTABSID].tGiftInfo.nNum
+end
+
+-- 设置购买次数
+local function BusThreeGrandGift_SetBuyNum(human, nAddNum)
+    human.db.absAct[BUSTHREEGRANDGIFTABSID].tGiftInfo.nNum = human.db.absAct[BUSTHREEGRANDGIFTABSID].tGiftInfo.nNum + nAddNum
+end
+
+-- 获取当前免费奖励状态
+local function BusThreeGrandGift_GetFreeStatus(human, nID)
+    return human.db.absAct[BUSTHREEGRANDGIFTABSID].tGiftInfo.tStatus[nID].nFreeStatus
+end
+
+-- 设置免费奖励状态
+local function BusThreeGrandGift_SetFreeStatus(human, nID, nValue)
+    human.db.absAct[BUSTHREEGRANDGIFTABSID].tGiftInfo.tStatus[nID].nFreeStatus = nValue
+end
+
+-- 获取当前付费奖励状态
+local function BusThreeGrandGift_GetPayStatus(human, nID)
+    return human.db.absAct[BUSTHREEGRANDGIFTABSID].tGiftInfo.tStatus[nID].nPayStatus
+end
+
+-- 设置付费奖励状态
+local function BusThreeGrandGift_SetPayStatus(human, nID, nValue)
+    human.db.absAct[BUSTHREEGRANDGIFTABSID].tGiftInfo.tStatus[nID].nPayStatus = nValue
+end
+
+-----------------------------------客户端请求-----------------------------
+function BusThreeGrandGift_Query(human)
+    BusThreeGrandGift_CheckAndResetDB(human)
+
+    local tMsgData = Msg.gc.GC_NEW_BUSTHREEACT_GRANDGIFT_QUERY
+    tMsgData.tList[0] = 0
+    for nID, v in ipairs(tGrandGiftConf) do
+        tMsgData.tList[0] = tMsgData.tList[0] + 1
+        local tData = tMsgData.tList[tMsgData.tList[0]]
+        tData.nID = nID
+        tData.nFreeStatus = BusThreeGrandGift_GetFreeStatus(human, nID)
+        local nPayStatus = BusThreeGrandGift_GetPayStatus(human, nID)
+        tData.nPayStatus = CommonDefine.COMMON_PRIZE_STATE_NOGET
+        tData.bBuy = 0
+        if nPayStatus == BUSTHREEGRANDGIFT_PAY_CANGET then
+            tData.nPayStatus = CommonDefine.COMMON_PRIZE_STATE_CANGET
+        elseif BUSTHREEGRANDGIFT_PAY_GET == nPayStatus then
+            tData.nPayStatus = CommonDefine.COMMON_PRIZE_STATE_GET
+        end
+
+        if nPayStatus ~= BUSTHREEGRANDGIFT_PAY_NOGET and BUSTHREEGRANDGIFT_PAY_HUOYUE ~= nPayStatus then
+            tData.bBuy = 1
+        end
+
+        tData.nFinishNum = BusThreeGrandGift_GetBuyNum(human)
+        tData.nNeedNum = v.nNeedNum
+
+        -- 购买项
+        BuyLogic.fontBuyItem(human, tData.tBuyItem, v.nBuyID)
+
+        tData.tFreePrize[0] = #v.FreePrize
+        for i, tItem in ipairs(v.FreePrize) do
+            local nGoodsID = tItem[1]
+            local nGoodsNum = tItem[2]
+
+            Grid.makeItem(tData.tFreePrize[i], nGoodsID, nGoodsNum)
+        end
+
+        tData.tPayPrize[0] = #v.PayPrize
+        for i, tItem in ipairs(v.PayPrize) do
+            local nGoodsID = tItem[1]
+            local nGoodsNum = tItem[2]
+
+            Grid.makeItem(tData.tPayPrize[i], nGoodsID, nGoodsNum)
+        end
+    end
+
+    Msg.send(tMsgData, human.fd)
+end
+
+function BusThreeGrandGift_Get(human)
+    local tGoods = {}
+    for nID, v in ipairs(tGrandGiftConf) do
+        local nFreeStatus = BusThreeGrandGift_GetFreeStatus(human, nID)
+        if CommonDefine.COMMON_PRIZE_STATE_CANGET == nFreeStatus then
+            BusThreeGrandGift_SetFreeStatus(human, nID, CommonDefine.COMMON_PRIZE_STATE_GET)
+            for _, tItem in ipairs(v.FreePrize) do
+                local nGoodsID = tItem[1]
+                local nGoodsNum = tItem[2]
+
+                if not tGoods[nGoodsID] then
+                    tGoods[nGoodsID] = 0
+                end
+
+                tGoods[nGoodsID] = tGoods[nGoodsID] + nGoodsNum
+            end
+        end
+
+        local nPayStatus = BusThreeGrandGift_GetPayStatus(human, nID)
+        if BUSTHREEGRANDGIFT_PAY_CANGET == nPayStatus then
+            BusThreeGrandGift_SetPayStatus(human, nID, BUSTHREEGRANDGIFT_PAY_GET)
+            for _, tItem in ipairs(v.PayPrize) do
+                local nGoodsID = tItem[1]
+                local nGoodsNum = tItem[2]
+
+                if not tGoods[nGoodsID] then
+                    tGoods[nGoodsID] = 0
+                end
+
+                tGoods[nGoodsID] = tGoods[nGoodsID] + nGoodsNum
+            end
+        end
+    end
+
+    if nil ~= _G.next(tGoods) then
+        local tItem = {}
+        for nGoodID, nGoodNum in pairs(tGoods) do
+            table.insert(tItem, {nGoodID, nGoodNum})
+        end
+
+        BagLogic.addItemList(human, tItem, "BusThreeGrandGift")
+        BusThreeGrandGift_Query(human)
+
+        YunYingLogic.sendBanner(human)
+        local config = AbsActExcel.absActivity[BUSTHREEGRANDGIFTABSID]
+        YunYingLogic.sendGroupUpdate(YYInfo[BUSTHREEGRANDGIFTABSID], human, config.panelID)
+    end
+end
+
+-----------------------------------外部调用-----------------------------
+function isOpen(human, YYInfo, funcConfig)
+    print("[BusThreeGrandGift_isOpen] 进入判断")
+    local state, endTime, startTime = AbsActLogic.isStarted(human, funcConfig and funcConfig.funcID or BUSTHREEGRANDGIFTABSID)
+    if not state then 
+        print("[BusThreeGrandGift_isOpen] 当前活动未开启")
+        return 
+    end
+    print("[BusThreeGrandGift_isOpen] 进入判断 endTime = "..endTime.." startTime = "..startTime)
+    return true, endTime, startTime
+end
+
+function isActive(human, YYInfo, funcConfig)
+    return not isOpen(human, YYInfo, funcConfig)
+end
+
+function isRed(human, YYInfo, absActConfig)
+    BusThreeGrandGift_CheckAndResetDB(human)
+
+    for nID, v in ipairs(tGrandGiftConf) do
+        local nFreeStatus = BusThreeGrandGift_GetFreeStatus(human, nID)
+        local nPayStatus = BusThreeGrandGift_GetPayStatus(human, nID)
+        if CommonDefine.COMMON_PRIZE_STATE_CANGET == nFreeStatus or
+            BUSTHREEGRANDGIFT_PAY_CANGET == nPayStatus then
+            return true
+        end
+    end
+
+    return false
+end
+
+function onCharge(human, price, funcID, buyID)
+    print("[BusThreeGrandGift_onCharge] 进入购买 buyID = "..buyID)
+
+    BusThreeGrandGift_CheckAndResetDB(human)
+
+    for nID, v in ipairs(tGrandGiftConf) do
+        if v.nBuyID == buyID then
+            local nPayStatus = BusThreeGrandGift_GetPayStatus(human, nID)
+            if BUSTHREEGRANDGIFT_PAY_NOGET == nPayStatus then
+                BusThreeGrandGift_SetPayStatus(human, nID, BUSTHREEGRANDGIFT_PAY_BUY)
+            elseif BUSTHREEGRANDGIFT_PAY_HUOYUE == nPayStatus then
+                BusThreeGrandGift_SetPayStatus(human, nID, BUSTHREEGRANDGIFT_PAY_CANGET)
+            end
+        end
+    end
+
+    print("[BusThreeGrandGift_onCharge] 发送协议完成")
+
+    BusThreeGrandGift_Query(human)
+    -- BusOneActivityTask.BusOneTask_SendRed(human)
+end
+
+function BusThreeGrandGift_NumChange(human, nNum)
+    if 0 >= nNum then
+        return
+    end
+
+    BusThreeGrandGift_CheckAndResetDB(human)
+    local nOldNum = BusThreeGrandGift_GetBuyNum(human)
+    BusThreeGrandGift_SetBuyNum(human, nNum)
+
+    local nNewNum = nOldNum + nNum
+    local bSend = false
+    for nID, v in ipairs(tGrandGiftConf) do
+        if nNewNum >= v.nNeedNum then
+            local nFreeStatus = BusThreeGrandGift_GetFreeStatus(human, nID)
+            local nPayStatus = BusThreeGrandGift_GetPayStatus(human, nID)
+            if nFreeStatus == CommonDefine.COMMON_PRIZE_STATE_NOGET then
+                BusThreeGrandGift_SetFreeStatus(human, nID, CommonDefine.COMMON_PRIZE_STATE_CANGET)
+                bSend = true
+            end
+
+            if BUSTHREEGRANDGIFT_PAY_NOGET == nPayStatus then
+                BusThreeGrandGift_SetPayStatus(human, nID, BUSTHREEGRANDGIFT_PAY_HUOYUE)
+                bSend = true
+            elseif BUSTHREEGRANDGIFT_PAY_BUY == nPayStatus then
+                BusThreeGrandGift_SetPayStatus(human, nID, BUSTHREEGRANDGIFT_PAY_CANGET)
+                bSend = true
+            end
+        end
+    end
+
+    if true == bSend then
+        YunYingLogic.sendBanner(human)
+        -- BusThreeActivityTask.BusOneTask_SendRed(human)
+    end
+end
+
+-- function GetRemainNum(human, nBuyID)
+--     for nID, v in ipairs(tGrandGiftConf) do
+--         if v.nBuyID == nBuyID then
+--             local nPayStatus = BusThreeGrandGift_GetPayStatus(human, nID)
+--             if nPayStatus == BUSTHREEGRANDGIFT_PAY_NOGET or BUSTHREEGRANDGIFT_PAY_HUOYUE == nPayStatus then
+--                 return 1
+--             else
+--                 return 0
+--             end
+--         end
+--     end
+-- end

+ 577 - 0
script/module/absAct/BusThreeActTask.lua

@@ -0,0 +1,577 @@
+--------------------------------
+-- 文件名       :   BusThreeActTask.lua
+-- 文件说明     :   新商业活动3-任务
+-- 创建时间     :   2025/09/02
+-- 创建人       :   FC
+--------------------------------
+
+local Util = require("common.Util")
+local Msg = require("core.Msg")
+local Grid = require("bag.Grid")
+local BagLogic = require("bag.BagLogic")
+local CommonDefine = require("common.CommonDefine")
+local BusThreeActConf = require("excel.BusThreeActivity")
+local ObjHuman = require("core.ObjHuman")
+local TriggerDefine = require("trigger.TriggerDefine")
+local TriggerLogic = require("trigger.TriggerLogic")
+local ServerCommerceManager = require("serverCommerce.ServerCommerceManager")
+local AbsActLogic = require("absAct.AbsActLogic")
+local Broadcast = require("broadcast.Broadcast")
+local Lang = require("common.Lang")
+local YunYingLogic = require("yunying.YunYingLogic")
+local AbsActExcel = require("excel.absAct")
+
+local BUSTHREETASKABSID = 7401        -- 对应ABS活动ID
+
+----------------------------------------- 内部处理开始 -------------------------------------
+-- 配置
+local function BusThreeActTask_GetTaskCof()
+    return BusThreeActConf.Task
+end
+
+local function BusThreeActTask_GetTaskPointCof()
+    return BusThreeActConf.TaskPoint
+end
+
+-- 订阅事件
+local function BusThreeActTask_SubEvent(uuid, nEventType)
+    TriggerLogic.SubscribeEvent(nEventType, uuid, BusThreeActTask_EventCallBack)
+end
+
+-- 创建DB数据
+local function CreatDB(human)
+    human.db.absAct[BUSTHREETASKABSID].Task = {
+        nTaskPoint = 0,             -- 任务积分
+        TaskPrize = {},             -- 任务数据
+        TaskPointPrize = {},        -- 任务积分奖励
+    }
+
+    local tConf = BusThreeActTask_GetTaskCof()
+    local tEvnetType = {}
+    local tDBTask = human.db.absAct[BUSTHREETASKABSID].Task.TaskPrize
+    for nID, v in ipairs(tConf) do
+        if not tDBTask[v.nTaskType] then
+            tDBTask[v.nTaskType] = {
+                nFinishNum = 0,     -- 完成次数
+                taskStatus = {},    -- 任务状态
+            }
+        end
+
+        tDBTask[v.nTaskType].taskStatus[nID] = CommonDefine.COMMON_PRIZE_STATE_NOGET
+
+        if not tEvnetType[v.nTaskType] then
+            BusThreeActTask_SubEvent(human.db._id, v.nTaskType)
+            tEvnetType[v.nTaskType] = 1
+        end
+    end
+
+    tConf = BusThreeActTask_GetTaskPointCof()
+    local tDBTaskPointPrize = human.db.absAct[BUSTHREETASKABSID].Task.TaskPointPrize
+    for nID, v in pairs(tConf) do
+        if not tDBTaskPointPrize[nID] then
+            tDBTaskPointPrize[nID] = CommonDefine.COMMON_PRIZE_STATE_NOGET
+        end
+    end
+
+    print("[BusThreeActTask_CreatDB] 战区任务 初始化数据完成 name = "..human.db.name)
+    return true
+end
+
+local function CheckAndCreatDB(human)
+    if not human.db.absAct[BUSTHREETASKABSID] or nil == _G.next(human.db.absAct[BUSTHREETASKABSID]) 
+        or not human.db.absAct[BUSTHREETASKABSID].Task then
+            CreatDB(human)
+    end
+end
+
+-- 获取任务奖励DB数据
+local function BusThreeActTask_GetTaskDB(human)
+    if not human.db.absAct[BUSTHREETASKABSID].Task then
+        human.db.absAct[BUSTHREETASKABSID].Task = {}
+        CreatDB(human)
+    end
+
+    return human.db.absAct[BUSTHREETASKABSID].Task
+end
+
+-- 获取任务状态
+local function BusThreeActTask_GetTaskStatus(human, nID, nTaskType)
+    local tDBData = BusThreeActTask_GetTaskDB(human)
+
+    if not tDBData.TaskPrize or not tDBData.TaskPrize[nTaskType] or not tDBData.TaskPrize[nTaskType].taskStatus[nID] then
+        print("[BusThreeActTask_GetTaskStatus] 不存在对应的DB数据!!! 没有初始化吗?")
+        return CommonDefine.COMMON_PRIZE_STATE_NOGET
+    end
+
+    return tDBData.TaskPrize[nTaskType].taskStatus[nID]
+end
+
+-- 设置任务状态
+local function BusThreeActTask_SetTaskStatus(human, nID, nTaskType, nValue)
+    local tDBData = BusThreeActTask_GetTaskDB(human)
+
+    tDBData.TaskPrize[nTaskType].taskStatus[nID] = nValue
+end
+
+-- 获取任务完成次数
+local function BusThreeActTask_GetTaskFinishNum(human, nTaskType)
+    local tDBData = BusThreeActTask_GetTaskDB(human)
+    if not tDBData.TaskPrize[nTaskType] then
+        return -1
+    end
+
+    return tDBData.TaskPrize[nTaskType].nFinishNum
+end
+
+-- 增加任务完成次数
+local function BusThreeActTask_AddTaskFinishNum(human, nTaskType, nAddNum)
+    local tDBData = BusThreeActTask_GetTaskDB(human)
+    if not tDBData.TaskPrize[nTaskType] then
+        return
+    end
+
+    tDBData.TaskPrize[nTaskType].nFinishNum = tDBData.TaskPrize[nTaskType].nFinishNum + nAddNum
+end
+
+-- 获取任务积分
+local function BusThreeActTask_GetTaskPoint(human)
+    local tDBData = BusThreeActTask_GetTaskDB(human)
+    return tDBData.nTaskPoint
+end
+
+-- 增加任务积分
+local function BusThreeActTask_AddTaskPoint(human, nPoint)
+    local tDBData = BusThreeActTask_GetTaskDB(human)
+    tDBData.nTaskPoint = tDBData.nTaskPoint + nPoint
+end
+
+-- 获取任务积分奖励状态
+local function BusThreeActTask_GetTaskPointPrizeStatus(human, nID)
+    local tDBData = BusThreeActTask_GetTaskDB(human)
+    if not tDBData.TaskPointPrize or not tDBData.TaskPointPrize[nID] then
+        return CommonDefine.COMMON_PRIZE_STATE_NOGET
+    end
+
+    return tDBData.TaskPointPrize[nID]
+end
+
+-- 设置 任务积分奖励状态
+local function BusThreeActTask_SetTaskPointPrizeStatus(human, nID, nValue)
+    local tDBData = BusThreeActTask_GetTaskDB(human)
+    tDBData.TaskPointPrize[nID] = nValue
+end
+
+-- 检查任务是否完成
+local function BusThreeActTask_CheckTaskStatus(human, nTaskType)
+    local tConf = BusThreeActTask_GetTaskCof()
+    local nNowFinishNum = BusThreeActTask_GetTaskFinishNum(human, nTaskType)
+    local nDay
+    local bSendRed = false
+    for nID, v in ipairs(tConf) do
+        if v.nTaskType == nTaskType then
+            if nNowFinishNum >= v.nValue then
+                local nState = BusThreeActTask_GetTaskStatus(human, nID, nTaskType)
+                if CommonDefine.COMMON_PRIZE_STATE_NOGET == nState then
+                    bSendRed = true
+                    BusThreeActTask_SetTaskStatus(human, nID, v.nTaskType, CommonDefine.COMMON_PRIZE_STATE_CANGET)
+                    -- BusThreeActTask_AddPoint(human, 1)
+                    if not nDay then
+                        nDay = v.nDay
+                    end
+                end
+            else
+                break
+            end
+        end
+    end
+
+    if true == bSendRed then
+        YunYingLogic.sendBanner(human)
+        local config = AbsActExcel.absActivity[BUSTHREETASKABSID]
+        YunYingLogic.sendGroupUpdate(YYInfo[BUSTHREETASKABSID], human, config.panelID)
+    end
+end
+
+-- 检查任务点数奖励状态
+local function BusThreeActTask_CheckTaskPointStatus(human)
+    local nNowPoint = BusThreeActTask_GetTaskPoint(human)
+    local tConf = BusThreeActTask_GetTaskPointCof()
+
+    local bSendClient = false
+    for nID, v in ipairs(tConf) do
+        if nNowPoint >= v.nPoint then
+            local nState = BusThreeActTask_GetTaskPointPrizeStatus(human, nID)
+            if CommonDefine.COMMON_PRIZE_STATE_NOGET == nState then
+                bSendClient = true
+                BusThreeActTask_SetTaskPointPrizeStatus(human, nID, CommonDefine.COMMON_PRIZE_STATE_CANGET)
+            end
+        else
+            break
+        end
+    end
+
+    if true == bSendClient then
+        BusThreeActTask_QueryTaskPoint(human)
+    end
+end
+
+----------------------------------------回调处理---------------------------------------------------
+-- 事件回调通用处理
+local function BusThreeActTask_EvnentCommon(nEventType, uuid, nValue)
+    print("[BusThreeActTask_EvnentCommon] 事件回调通用处理 nEventType = "..nEventType.." uuid = "..uuid)
+    local human = ObjHuman.onlineUuid[uuid]
+    if not human then
+        print("[BusThreeActTask_EvnentCommon] 玩家不在线了? nEventType = "..nEventType)
+        return
+    end
+
+    print("[BusThreeActTask_EvnentCommon] nEventType = "..nEventType.." nValue = "..nValue.." name = "..human.db.name)
+
+    local nOldNum = BusThreeActTask_GetTaskFinishNum(human, nEventType)
+
+    print("[BusThreeActTask_EvnentCommon] 久的次数 nOldNum = "..nOldNum)
+
+    -- 增加完成次数
+    BusThreeActTask_AddTaskFinishNum(human, nEventType, nValue)
+
+    -- 检查任务状态
+    BusThreeActTask_CheckTaskStatus(human, nEventType)
+end
+
+-- 事件-获得英雄处理
+local function BusThreeActTask_EvnentGetHero(nEventType, uuid, nValue1, nValue2)
+    local human = ObjHuman.onlineUuid[uuid]
+    if not human then
+        return
+    end
+    
+    local nNum = nValue1
+    local nStar = nValue2
+
+    print("[BusThreeActTask_EvnentGetHero] nEventType = "..nEventType.." nNum = "..nNum.." nStar = "..nStar.." name = "..human.db.name)
+
+    local bCheck = false
+    local tConf = BusThreeActTask_GetTaskCof()
+    for nID, v in ipairs(tConf) do
+        if v.nTaskType == nEventType then
+            if not v.nTaskArgument or v.nTaskArgument == "" then
+                print("[BusThreeActTask_EvnentGetHero] 获得英雄但是没有获取到对应的配置参数要求")
+            else
+                --print("[BusThreeActTask_EvnentGetHero] 存在对应参数 nTaskArgument = "..v.nTaskArgument)
+                local tTaskArgument = Util.split(v.nTaskArgument , "|")
+                -- table.print_lua_table(tTaskArgument)
+                if 2 ~= #tTaskArgument then
+                    print("[BusThreeActTask_EvnentGetHero] 获取的任务 参数数量不正确")
+                else
+                    if nNum >= tonumber(tTaskArgument[1]) and nStar == tonumber(tTaskArgument[2]) then
+                        --print("BusThreeActTask_EvnentGetHero 条件满足")
+                        BusThreeActTask_AddTaskFinishNum(human, nEventType, 1)
+                        --local nNewNum = BusThreeActTask_GetTaskFinishNum(human, nEventType)
+                        --print("BusThreeActTask_EvnentGetHero 条件满足, 新的数量为 nNewNum = "..nNewNum)
+                        bCheck = true
+                    end
+                end
+            end
+        end
+    end
+
+    BusThreeActTask_CheckTaskStatus(human, nEventType)
+end
+
+-- 事件处理
+local tEventHandler = nil
+-- 起服处理
+function Init()
+    tEventHandler = {
+        [TriggerDefine.EVENT_TYPE_SWEEP] = BusThreeActTask_EvnentCommon,
+        [TriggerDefine.CHAT_TIMES] = BusThreeActTask_EvnentCommon,
+        [TriggerDefine.FRIEND_COMBAT] = BusThreeActTask_EvnentCommon,
+        [TriggerDefine.EVENT_TYPE_FINDSTAR] = BusThreeActTask_EvnentCommon,
+        [TriggerDefine.EVENT_TYPE_FATESUMMON] = BusThreeActTask_EvnentCommon,
+        [TriggerDefine.EVENT_TYPE_OPENBOX] = BusThreeActTask_EvnentCommon,
+        [TriggerDefine.EVENT_TYPE_CHAMPIONSNUM] = BusThreeActTask_EvnentCommon,
+        [TriggerDefine.EVENT_TYPE_GETHERO] = BusThreeActTask_EvnentGetHero,
+        [TriggerDefine.EVENT_TYPE_SHOPBUY] = BusThreeActTask_EvnentCommon,
+        [TriggerDefine.EVENT_TYPE_UNIONSKILLUP] = BusThreeActTask_EvnentCommon,
+        [TriggerDefine.DRAWCALL_SERNIOR_CNT] = BusThreeActTask_EvnentCommon,
+    }
+
+    print("[CommerceActTask - Init] tEventHandler 初始化完成")
+end
+
+----------------------------------------- 外部调用开始 -------------------------------------
+function BusThreeActTask_EventCallBack(nEventType, uuid, nValue1, nValue2)
+    if not tEventHandler then
+        Init()
+    end
+
+    if not tEventHandler or not tEventHandler[nEventType] then
+        print("[BusThreeActTask_EventCallBack] 不存在对应的处理函数 nEventType = "..nEventType)
+        return
+    end
+
+    print("[BusThreeActTask_EventCallBack] 收到事件触发回调 nEventType = "..nEventType)
+    pcall(tEventHandler[nEventType], nEventType, uuid, nValue1, nValue2)
+end
+
+function BusThreeActTask_AddPoint(human, nAddPoint)
+    -- 增加积分
+    BusThreeActTask_AddTaskPoint(human, nAddPoint)
+
+    -- 检查积分奖励状态
+    BusThreeActTask_CheckTaskPointStatus(human)
+end
+
+----------------------------------------- 客户端请求 -------------------------------------
+-- 请求战区集结任务信息
+function BusThreeActTask_QueryTask(human, nDay)
+    local state, nEndTime, nOpenTime = AbsActLogic.isStarted(human, BUSTHREETASKABSID)
+    if not state then
+        return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
+    end
+
+    print("[BusThreeActTask_QueryTask] 进入查询任务信息 nDay = "..nDay.." name = "..human.db.name)
+
+    CheckAndCreatDB(human)
+
+    local tConf = BusThreeActTask_GetTaskCof()
+
+    local nDiffDay = Util.diffDay(nOpenTime) + 1
+    local tMsgData = Msg.gc.GC_NEW_BUSTHREEACT_TASKQUERY
+    tMsgData.nDay = nDay
+    tMsgData.nNowDay = nDiffDay
+    tMsgData.nNowPoint = BusThreeActTask_GetTaskPoint(human)
+    tMsgData.leftTime = nEndTime - os.time()
+
+    print("[BusThreeActTask_QueryTask] nDay = "..nDay.." nDiffDay = "..nDiffDay.." name = "..human.db.name)
+
+    local tDay = {}
+    local tRed = tMsgData.tRed
+    tRed[0] = 0
+    local tListData = tMsgData.list
+    tListData[0] = 0
+    for nID, v in ipairs(tConf) do
+        if v.nDay == nDay then
+            tListData[0] = tListData[0] + 1
+            local tNode = tListData[tListData[0]]
+            tNode.nID = nID
+            tNode.nState = BusThreeActTask_GetTaskStatus(human, nID, v.nTaskType)
+            tNode.nDay = v.nDay
+            tNode.nValue = v.nValue
+            -- tNode.nPoint = v.nPoint
+            tNode.Desc = v.szDes
+            tNode.nFinish = BusThreeActTask_GetTaskFinishNum(human, v.nTaskType)
+            tNode.item[0] = #v.Prize
+
+            for i, tItemData in ipairs(v.Prize) do
+                Grid.makeItem(tNode.item[i], tItemData[1], tItemData[2])
+            end
+        end
+
+        if not tDay[v.nDay] then
+            tDay[v.nDay] = 1
+            tRed[0] = tRed[0] + 1
+            tRed[v.nDay] = 0
+        end
+
+        if tRed[v.nDay] == 0 and v.nDay <= nDiffDay then
+            local nState = BusThreeActTask_GetTaskStatus(human, nID, v.nTaskType)
+            if nState == CommonDefine.COMMON_PRIZE_STATE_CANGET then
+                tRed[v.nDay] = 1
+            end
+        end
+    end
+
+    Msg.send(tMsgData, human.fd)
+    print("[BusThreeActTask_QueryTask] 发送任务信息完成 name = "..human.db.name)
+end
+
+-- 请求领取任务奖励
+function BusThreeActTask_GetTaskPrize(human, nDay)
+    local tConf = BusThreeActTask_GetTaskCof()
+    local tGoods = {}
+
+    local nFinishNum = 0
+    for nID, v in ipairs(tConf) do
+        if v.nDay == nDay then
+            local nState = BusThreeActTask_GetTaskStatus(human, nID, v.nTaskType)
+            if CommonDefine.COMMON_PRIZE_STATE_CANGET == nState then
+                for i, tItemData in ipairs(v.Prize) do
+                    if not tGoods[tItemData[1]] then
+                        tGoods[tItemData[1]] = 0
+                    end
+
+                    tGoods[tItemData[1]] = tGoods[tItemData[1]] + tItemData[2]
+                end
+
+                BusThreeActTask_SetTaskStatus(human, nID, v.nTaskType, CommonDefine.COMMON_PRIZE_STATE_GET)
+                nFinishNum = nFinishNum + 1
+            end
+        end
+    end
+
+    if nil ~= _G.next(tGoods) then
+        local tItem = {}
+        for nID, nNum in pairs(tGoods) do
+            table.insert(tItem, {nID, nNum})
+        end
+
+        BagLogic.addItemList(human, tItem, "BusThreeTask")
+
+        BusThreeActTask_AddPoint(human, nFinishNum)
+
+        BusThreeActTask_QueryTask(human, nDay)
+     
+        BusThreeActTask_QueryTaskPoint(human)
+
+        YunYingLogic.sendBanner(human)
+        local config = AbsActExcel.absActivity[BUSTHREETASKABSID]
+        YunYingLogic.sendGroupUpdate(YYInfo[BUSTHREETASKABSID], human, config.panelID)
+    end
+end
+
+-- 请求任务积分信息
+function BusThreeActTask_QueryTaskPoint(human)
+    print("[BusThreeActTask_QueryTaskPoint] 进入查询任务积分信息 name = "..human.db.name)
+    local tConf = BusThreeActTask_GetTaskPointCof()
+
+    local tMsgData = Msg.gc.GC_NEW_BUSTHREEACT_TASKPOINTQUERY
+    tMsgData.nNowPoint = BusThreeActTask_GetTaskPoint(human)
+
+    CheckAndCreatDB(human)
+
+    local tListData = tMsgData.listPoint
+    tListData[0] = 0
+    for nID, v in ipairs(tConf) do
+        tListData[0] = tListData[0] + 1
+        local tNode = tListData[tListData[0]]
+        tNode.nID = nID
+        tNode.nNeedPoint = v.nPoint
+        tNode.nState = BusThreeActTask_GetTaskPointPrizeStatus(human, nID)
+        tNode.item[0] = #v.Prize
+
+        for i, tItemData in ipairs(v.Prize) do
+            Grid.makeItem(tNode.item[i], tItemData[1], tItemData[2])
+        end
+    end
+
+    Msg.send(tMsgData, human.fd)
+end
+
+-- 领取任务积分奖励
+function BusThreeActTask_GetTaskPointPrize(human)
+    local tConf = BusThreeActTask_GetTaskPointCof()
+
+    local tGoods = {}
+    for nID, v in ipairs(tConf) do
+        local nState = BusThreeActTask_GetTaskPointPrizeStatus(human, nID)
+        if CommonDefine.COMMON_PRIZE_STATE_CANGET == nState then
+            for i, tItemData in ipairs(v.Prize) do
+                if not tGoods[tItemData[1]] then
+                    tGoods[tItemData[1]] = 0
+                end
+
+                tGoods[tItemData[1]] = tGoods[tItemData[1]] + tItemData[2]
+            end
+
+            BusThreeActTask_SetTaskPointPrizeStatus(human, nID, CommonDefine.COMMON_PRIZE_STATE_GET)
+        end
+    end
+
+    if nil ~= _G.next(tGoods) then
+        local tItem = {}
+        for nID, nNum in pairs(tGoods) do
+            table.insert(tItem, {nID, nNum})
+        end
+
+        BagLogic.addItemList(human, tItem, "BusThreeTask")
+        BusThreeActTask_QueryTaskPoint(human)
+
+        YunYingLogic.sendBanner(human)
+        local config = AbsActExcel.absActivity[BUSTHREETASKABSID]
+        YunYingLogic.sendGroupUpdate(YYInfo[BUSTHREETASKABSID], human, config.panelID)
+    end
+end
+
+function isRed(human)
+    local tConf = BusThreeActTask_GetTaskCof()
+    local state, nEndTime, nOpenTime = AbsActLogic.isStarted(human, BUSTHREETASKABSID)
+    if not state then
+        return false
+    end
+
+    CheckAndCreatDB(human)
+    
+    if 0 >= nOpenTime then
+        print("[BusThreeActTask_isRed] 不正确的活动开启时间")
+        return false
+    end
+
+    local nDiffDay = Util.diffDay(nOpenTime) + 1
+    for nID, v in ipairs(tConf) do
+        if v.nDay <= nDiffDay then
+            local nState = BusThreeActTask_GetTaskStatus(human, nID, v.nTaskType)
+            if CommonDefine.COMMON_PRIZE_STATE_CANGET == nState then
+                return true
+            end
+        end
+    end
+
+    tConf = BusThreeActTask_GetTaskPointCof()
+    for nID, v in ipairs(tConf) do
+        local nState = BusThreeActTask_GetTaskPointPrizeStatus(human, nID)
+        if CommonDefine.COMMON_PRIZE_STATE_CANGET == nState then
+            return true
+        end
+    end
+
+    return false
+end
+
+-- 订阅任务数据
+function BusThreeActTask_HumanSubEvent(human)
+    local tConf = BusThreeActTask_GetTaskCof()
+    local tTaskType = {}
+
+    for nID, v in ipairs(tConf) do
+        if not tTaskType[v.nTaskType] then
+            local nState = BusThreeActTask_GetTaskStatus(human, nID, v.nTaskType)
+            -- 没有完成才订阅
+            if nState == CommonDefine.COMMON_PRIZE_STATE_NOGET then
+                tTaskType[v.nTaskType] = 1
+            end
+        end
+    end
+
+    -- 订阅事件
+    for nTaskType, v in pairs(tTaskType) do
+        BusThreeActTask_SubEvent(human.db._id, nTaskType)
+        print("[BusThreeActTask_SubEvent] 玩家订阅了事件 nTaskType = "..nTaskType)
+    end
+end
+
+function onLogin(human)
+    local state, nEndTime, nOpenTime = AbsActLogic.isStarted(human, BUSTHREETASKABSID)
+    if not state then
+        return
+    end
+
+    BusThreeActTask_HumanSubEvent(human)
+    print("[BusThreeActTask_onLogin] 玩家登录订阅事件完成 name = "..human.db.name)
+end
+
+
+function isOpen(human, YYInfo, funcConfig)
+    print("[BusThreeActTask__isOpen] 进入判断")
+    local state, endTime, startTime = AbsActLogic.isStarted(human, funcConfig and funcConfig.funcID or BUSTHREETASKABSID)
+    if not state then 
+        print("[BusThreeActTask_isOpen] 当前活动未开启")
+        return 
+    end
+    print("[BusThreeActTask__isOpen] 进入判断 endTime = "..endTime.." startTime = "..startTime)
+    return true, endTime, startTime
+end
+
+function isActive(human, YYInfo, funcConfig)
+    return not isOpen(human, YYInfo, funcConfig)
+end

+ 377 - 0
script/module/absAct/CommonActBoss.lua

@@ -0,0 +1,377 @@
+local Msg = require("core.Msg")
+local Grid = require("bag.Grid")
+local BagLogic = require("bag.BagLogic")
+local AbsActLogic = require("absAct.AbsActLogic")
+local Broadcast = require("broadcast.Broadcast")
+local Lang = require("common.Lang")
+local Config = require("excel.commonact").ectype
+local CommonDefine = require("common.CommonDefine")
+local Util = require("common.Util")
+local CombatDefine = require("combat.CombatDefine")
+local CombatLogic = require("combat.CombatLogic")
+local YunYingLogic = require("yunying.YunYingLogic")
+local AbsActExcel = require("excel.absAct")
+
+
+local COMMONACTBOSSABSID = 7501
+local COMMONACTFREENUM = 3  -- 免费挑战次数
+local COMMONACTDAYID = 99
+local COMMONACTBOOSPRIZE = 1 -- BOSS奖励类型
+local COMMONACTFIGHTPRIZE = 2 -- 战斗奖励类型
+
+local CommonAct_BossID = nil
+local CommonAct_MapID = nil
+
+local function ComActBoss_CreateDB(human)
+    if not human.db.absAct[COMMONACTBOSSABSID] then
+        human.db.absAct[COMMONACTBOSSABSID] = {}
+    end
+    
+    human.db.absAct[COMMONACTBOSSABSID].tBossInfo = {
+        nFreeNum = COMMONACTFREENUM,
+        nFreeTime = os.time(),
+        nDamage = 0,
+        tPrizeInfo = {}
+    }
+
+    for nID, v in pairs(Config) do
+        if nID ~= COMMONACTDAYID then
+            human.db.absAct[COMMONACTBOSSABSID].tBossInfo.tPrizeInfo[nID] = CommonDefine.COMMON_PRIZE_STATE_NOGET
+        end
+    end
+end
+
+-- 检测并创建DB数据
+local function ComActBoss_CheckAndCreateDB(human)
+    if not human.db.absAct[COMMONACTBOSSABSID] or not human.db.absAct[COMMONACTBOSSABSID].tBossInfo then
+        ComActBoss_CreateDB(human)
+    end
+end
+
+-- 获取奖励数据
+local function CommonActBoss_GetPrizeData(human)
+    return human.db.absAct[COMMONACTBOSSABSID].tBossInfo.tPrizeInfo
+end
+
+-- 获取奖励状态
+local function CommonActBoss_GetPrizeStatus(human, nID)
+    local tPrizeInfo = CommonActBoss_GetPrizeData(human)
+    
+    return tPrizeInfo[nID]
+end
+
+-- 设置奖励状态
+local function CommonActBoss_SetPrizeStatus(human, nID, nValue)
+    local tPrizeInfo = CommonActBoss_GetPrizeData(human)
+
+    tPrizeInfo[nID] = nValue
+end
+
+-- 获取总伤害
+local function CommonActBoss_GetDamage(human)
+    return human.db.absAct[COMMONACTBOSSABSID].tBossInfo.nDamage
+end
+
+-- 增加总伤害
+local function CommonActBoss_AddDamage(human, nNum)
+    human.db.absAct[COMMONACTBOSSABSID].tBossInfo.nDamage = human.db.absAct[COMMONACTBOSSABSID].tBossInfo.nDamage + nNum
+end
+
+-- 获取免费次数
+local function CommonActBoss_GetFreeNum(human)
+    return human.db.absAct[COMMONACTBOSSABSID].tBossInfo.nFreeNum
+end
+
+-- 设置免费次数
+local function CommonActBoss_SetFreeNum(human, nNum)
+    human.db.absAct[COMMONACTBOSSABSID].tBossInfo.nFreeNum = nNum
+end
+
+-- 获取免费刷新时间
+local function CommonActBoss_GetFreeTime(human)
+    return human.db.absAct[COMMONACTBOSSABSID].tBossInfo.nFreeTime
+end
+
+-- 设置免费刷新时间
+local function CommonActBoss_SetFreeTime(human, nTime)
+    human.db.absAct[COMMONACTBOSSABSID].tBossInfo.nFreeTime = nTime
+end
+
+local function CommonActBoss_IsPrizeRed(human)
+    for nID, v in pairs(Config) do
+        if nID ~= COMMONACTDAYID then
+            local nState = CommonActBoss_GetPrizeStatus(human, nID)
+            if nState == CommonDefine.COMMON_PRIZE_STATE_CANGET then
+                return true
+            end
+        end
+    end
+
+    return false
+end
+
+
+function isRed(human)
+    local state, nEndTime, nOpenTime = AbsActLogic.isStarted(human, COMMONACTBOSSABSID)
+    if not state then
+        return false
+    end
+
+    ComActBoss_CheckAndCreateDB(human)
+
+    local nFreeNum = CommonActBoss_GetFreeNum(human)
+    if nFreeNum > 0 then
+        return true
+    end
+
+    return CommonActBoss_IsPrizeRed(human)
+end
+
+function isOpen(human, YYInfo, funcConfig)
+    local state, endTime, startTime = AbsActLogic.isStarted(human, funcConfig and funcConfig.funcID or COMMONACTBOSSABSID)
+    if not state then
+        print("[CommonActBoss_isOpen] 当前活动未开启")
+        return 
+    end
+    print("[CommonActBoss_isOpen] 进入判断 endTime = "..endTime.." startTime = "..startTime)
+    return true, endTime, startTime
+end
+
+function isActive(human, YYInfo, funcConfig)
+    return not isOpen(human, YYInfo, funcConfig)
+end
+
+function onZero(human, funcID)
+    local state, nEndTime, nOpenTime = AbsActLogic.isStarted(human, COMMONACTBOSSABSID)
+    if not state then
+        return
+    end
+
+    CommonActBoss_SetFreeNum(human, COMMONACTFREENUM)
+    CommonActBoss_SetFreeTime(human, os.time())
+end
+
+function onLogin(human, funcID)
+    local state, nEndTime, nOpenTime = AbsActLogic.isStarted(human, COMMONACTBOSSABSID)
+    if not state then
+        return
+    end
+
+    ComActBoss_CheckAndCreateDB(human)
+
+    local nFreeRefreshTime = CommonActBoss_GetFreeTime(human)
+    if true ~= Util.isSameDayByTimes(nFreeRefreshTime, os.time()) then
+        CommonActBoss_SetFreeNum(human, COMMONACTFREENUM)
+        CommonActBoss_SetFreeTime(human, os.time())
+    end
+end
+
+
+------------------------------------ 客户端请求处理开始 ---------------------------------
+function CommonActBoss_Query(human)
+    local state = AbsActLogic.isStarted(human, COMMONACTBOSSABSID)
+    if not state then
+        print("[CommonActBoss_Query] 当前活动未开启")
+        return
+    end
+
+    ComActBoss_CheckAndCreateDB(human)
+
+    local tMsgData = Msg.gc.GC_ABS_FESTIVAL_BOSS_QUERY
+    tMsgData.nNum = CommonActBoss_GetFreeNum(human)
+    tMsgData.nMaxNum = COMMONACTFREENUM
+    tMsgData.nHarm = CommonActBoss_GetDamage(human)
+    tMsgData.bRedPrize = CommonActBoss_IsPrizeRed(human) == true and 1 or 0
+
+    Msg.send(tMsgData, human.fd)
+end
+
+function CommonActBoss_QueryPrize(human)
+    local tMsgData = Msg.gc.GC_ABS_FESTIVAL_BOSS_REWARD
+    tMsgData.tPrize[0] = 0
+
+    for nID, v in pairs(Config) do
+        if v.nType == COMMONACTBOOSPRIZE then
+            tMsgData.tPrize[0] =  tMsgData.tPrize[0] + 1
+            local tData = tMsgData.tPrize[tMsgData.tPrize[0]]
+            tData.nID = nID
+            tData.nHarm = v.hurt
+            tData.nState = CommonActBoss_GetPrizeStatus(human, nID)
+
+            tData.tPrize[0] = #v.tPrize
+            for i, value in ipairs(v.tPrize) do
+                Grid.makeItem(tData.tPrize[i], value[1], value[2])
+            end
+        end
+    end
+
+    Msg.send(tMsgData, human.fd)
+end
+
+function CommonActBoss_GetPrize(human)
+    local tItem = {}
+
+    for nID, v in pairs(Config) do
+        if v.nType == COMMONACTBOOSPRIZE then
+            local nState = CommonActBoss_GetPrizeStatus(human, nID)
+            if CommonDefine.COMMON_PRIZE_STATE_CANGET == nState then
+                CommonActBoss_SetPrizeStatus(human, nID, CommonDefine.COMMON_PRIZE_STATE_GET)
+                for i, value in ipairs(v.tPrize) do
+                    if not tItem[value[1]] then
+                        tItem[value[1]] = 0
+                    end
+
+                    tItem[value[1]] = tItem[value[1]] + value[2]
+                end
+            end
+        end
+    end
+
+    if nil ~= _G.next(tItem) then
+        local tGoods = {}
+        for nID, nNum in pairs(tItem) do
+            table.insert(tGoods, {nID, nNum})
+        end
+
+        BagLogic.addItemList(human, tGoods, "CommonActBoss")
+        CommonActBoss_Query(human)
+        CommonActBoss_QueryPrize(human)
+        YunYingLogic.sendBanner(human)
+        local config = AbsActExcel.absActivity[COMMONACTBOSSABSID]
+        YunYingLogic.sendGroupUpdate(YYInfo[COMMONACTBOSSABSID], human, config.panelID)
+    end
+end
+
+------------------------------------ 战斗处理开始 ---------------------------------
+-- 调用开始战斗
+function fight(human, args, combatType)
+    if CombatDefine.COMBAT_TYPE34 ~= combatType then
+        print("[CommonActBoss_fight] 战斗类型不正确 combatType = "..combatType)
+        return
+    end
+
+    local nMapID = getMapID(human, nil)
+
+    -- print("[CommonActBoss_fight] 11111 combatType = "..combatType)
+    local nNowFreeNum = CommonActBoss_GetFreeNum(human)
+    if 0 >= nNowFreeNum then
+        return
+    end
+
+    nNowFreeNum = nNowFreeNum - 1
+    CommonActBoss_SetFreeNum(human, nNowFreeNum)
+
+    CombatLogic.combatBegin(human, nMapID, args, CombatDefine.COMBAT_TYPE34)
+    print("[CommonActBoss_fight] 2222 combatType = "..combatType)
+end
+
+-- 获取人物对战列表
+function getCombatObjList(human, side, args)
+    if not human then
+        print("[getCombatObjList] 获取进攻方,但是不存在对应的human")
+        return
+    end
+
+    if side ~= CombatDefine.ATTACK_SIDE then
+        return
+    end
+
+    print("[getCombatObjList] 进攻方 获取人物对战列表")
+    local objList, helpList, rolebase, formation,jiban, elfList = CombatLogic.getHumanObjList(human, CombatDefine.COMBAT_TYPE34)
+    if not objList or nil == _G.next(objList) then
+        print("[getCombatObjList] 没有获取到对应的进攻方防守阵容,取默认对战阵容")
+        objList, helpList, rolebase, formation,jiban, elfList = CombatLogic.getHumanObjList(human, CombatDefine.COMBAT_TYPE1)
+    end
+
+    return objList, helpList, rolebase, formation,jiban, elfList
+end
+
+-- 获取机器人对应战斗ID
+function getCombatMonsterOutID(human, side, args)
+    if side ~= CombatDefine.DEFEND_SIDE then
+        return
+    end
+
+    if not CommonAct_BOSSID then
+        for key, v in pairs(Config) do
+            if v.nMonsterOutID and v.nType == COMMONACTFIGHTPRIZE then
+                CommonAct_BOSSID = v.nMonsterOutID
+                break
+            end
+        end
+    end
+
+    print("[getCombatMonsterOutID] 获取到的战斗ID CommonAct_BOSSID = "..CommonAct_BOSSID)
+    return CommonAct_BOSSID
+end
+
+function getMapID(human, param)
+    if not CommonAct_MapID then
+        for key, v in pairs(Config) do
+            if v.mapID and v.nType == COMMONACTFIGHTPRIZE then
+                CommonAct_MapID = v.mapID
+                break
+            end
+        end
+    end
+
+    return CommonAct_MapID
+end
+
+function onFightEnd(human, result, combatType, defUuid, combatInfo)
+    local atkHurt = 0
+	for pos = 1, CombatDefine.COMBAT_HERO_CNT do
+		local obj = combatInfo.objList and combatInfo.objList[pos]
+		if obj then
+			atkHurt = atkHurt + obj.result[1]
+		end
+	end
+
+    -- 魔兽 造成伤害
+    for _,pos in ipairs(CombatDefine.SIDE2HELPPOS[CombatDefine.ATTACK_SIDE]) do
+		local pet = combatInfo.helpList and combatInfo.helpList[pos]
+		if pet and pet.isPet then
+            atkHurt = atkHurt + pet.result[1]
+		end
+	end
+
+    -- 精灵 造成伤害
+    for _,pos in ipairs(CombatDefine.SIDE2ELFPOS[CombatDefine.ATTACK_SIDE]) do
+		local elf = combatInfo.elfList and combatInfo.elfList[pos]
+		if elf then
+            atkHurt = atkHurt + elf.result[1]
+		end
+	end
+
+    local nNowDamage = CommonActBoss_GetDamage(human)
+    nNowDamage = nNowDamage + atkHurt
+
+    local bChange = false
+    local tPrize = nil
+    for nID, v in pairs(Config) do
+        if v.nType == COMMONACTBOOSPRIZE then
+            if nNowDamage >= v.hurt then
+                local nState = CommonActBoss_GetPrizeStatus(human, nID)
+                if CommonDefine.COMMON_PRIZE_STATE_NOGET == nState then
+                    CommonActBoss_SetPrizeStatus(human, nID, CommonDefine.COMMON_PRIZE_STATE_CANGET)
+                    bChange = true
+                end
+            else
+                bChange = true
+            end
+        else
+            tPrize = v.tPrize
+        end
+    end
+
+    if true == bChange then
+        YunYingLogic.sendBanner(human)
+        local config = AbsActExcel.absActivity[COMMONACTBOSSABSID]
+        YunYingLogic.sendGroupUpdate(YYInfo[COMMONACTBOSSABSID], human, config.panelID)
+        
+        CommonActBoss_AddDamage(human, atkHurt)
+        CommonActBoss_Query(human)
+    end
+
+    BagLogic.addItemList(human, tPrize, "CommonActBoss")
+end

+ 224 - 0
script/module/absAct/CommonActCharge.lua

@@ -0,0 +1,224 @@
+--------------------------------
+-- 文件名       :   CommonActCharge.lua
+-- 文件说明     :   通用节日活动-连充豪礼
+-- 创建时间     :   2025/09
+-- 创建人       :   FC
+--------------------------------
+
+local Msg = require("core.Msg")
+local Grid = require("bag.Grid")
+local BagLogic = require("bag.BagLogic")
+local AbsActLogic = require("absAct.AbsActLogic")
+local Broadcast = require("broadcast.Broadcast")
+local Lang = require("common.Lang")
+local Config = require("excel.commonact").allcharge
+local CommonDefine = require("common.CommonDefine")
+local YunYingLogic = require("yunying.YunYingLogic")
+local AbsActExcel = require("excel.absAct")
+
+
+local COMMONACTCHARGEABSID = 7503
+
+----------------------------------------- 内部处理开始 -------------------------------------
+-- 获取配置
+local function CommonActCharge_GetCof()
+    return Config
+end
+
+-- 初始化DB数据()
+function CreatDB(human)
+   if not human.db.absAct[COMMONACTCHARGEABSID] then
+        human.db.absAct[COMMONACTCHARGEABSID] = {}
+    end
+
+    if not human.db.absAct[COMMONACTCHARGEABSID].tPrizeData then
+        human.db.absAct[COMMONACTCHARGEABSID].tPrizeData = {}
+    end
+    
+    human.db.absAct[COMMONACTCHARGEABSID].nAllMoney = 0
+    for index, v in ipairs(Config) do
+        human.db.absAct[COMMONACTCHARGEABSID].tPrizeData[index] = CommonDefine.COMMON_PRIZE_STATE_NOGET
+    end
+
+    return true
+end
+
+-- 检测并创建DB数据
+local function CheckAndCreateDB(human)
+    if not human.db.absAct[COMMONACTCHARGEABSID] or not human.db.absAct[COMMONACTCHARGEABSID].tPrizeData then
+        CreatDB(human)
+    end
+end 
+
+-- 获取DB奖励数据
+local function CommonActCharge_GetDBPrizeData(human)
+    return human.db.absAct[COMMONACTCHARGEABSID].tPrizeData
+end
+
+-- 获取DB奖励状态
+local function CommonActCharge_GetDBPrizeStatus(human, nIndex)
+    local tPrizeData = CommonActCharge_GetDBPrizeData(human)
+    return tPrizeData[nIndex]
+end
+
+-- 设置DB奖励状态
+local function CommonActCharge_SetDBPrizeStatus(human, nIndex, nStatus)
+    local tPrizeData = CommonActCharge_GetDBPrizeData(human)
+    tPrizeData[nIndex] = nStatus
+end
+
+-- 获取DB天数充值金额
+local function CommonActCharge_GetDBDayCharge(human)
+    return human.db.absAct[COMMONACTCHARGEABSID].nAllMoney
+end
+
+-- 设置DB天数充值金额
+local function CommonActCharge_SetDBDayCharge(human, nAddMoney)
+    human.db.absAct[COMMONACTCHARGEABSID].nAllMoney = human.db.absAct[COMMONACTCHARGEABSID].nAllMoney + nAddMoney
+end
+
+
+----------------------------------------- 客户端请求处理开始 -------------------------------------
+-- 请求数据
+function CommonActCharge_Query(human)
+    CheckAndCreateDB(human)
+    
+    local tConf = CommonActCharge_GetCof()
+    local tMsgData = Msg.gc.GC_ABS_FESTIVAL_RECHARGE_QUERY
+
+    tMsgData.tPrize[0] = 0
+    tMsgData.nNowCharge = CommonActCharge_GetDBDayCharge(human)
+    local nLen = 0
+    for nID, v in ipairs(tConf) do
+        nLen = nLen + 1
+        local tPrizeData = tMsgData.tPrize[nLen]
+        tPrizeData.nID = nID
+        tPrizeData.nState = CommonActCharge_GetDBPrizeStatus(human, nID)
+        tPrizeData.nNeedCharge = v.nMoney
+
+        tPrizeData.tPrize[0] = #v.tPrize
+        for nIndex, tItem in ipairs(v.tPrize) do
+            local nGoodsID = tItem[1]
+            local nGoodsNum = tItem[2]
+
+            Grid.makeItem(tPrizeData.tPrize[nIndex], nGoodsID, nGoodsNum)
+        end
+    end
+
+    tMsgData.tPrize[0] = nLen
+    Msg.send(tMsgData, human.fd)
+end
+
+-- 请求领取奖励
+function CommonActCharge_Get(human, nIndex)
+    local tConf = CommonActCharge_GetCof()
+
+    local tItem = {}
+    for nID, v in ipairs(tConf) do
+        local nState = CommonActCharge_GetDBPrizeStatus(human, nID)
+        if CommonDefine.COMMON_PRIZE_STATE_CANGET == nState then
+            CommonActCharge_SetDBPrizeStatus(human, nID, CommonDefine.COMMON_PRIZE_STATE_GET)
+            for _, tPrize in ipairs(v.tPrize) do
+                if not tItem[tPrize[1]]  then
+                    tItem[tPrize[1]] = 0
+                end
+
+                tItem[tPrize[1]] = tItem[tPrize[1]] + tPrize[2]
+            end
+        end
+    end
+
+    if nil ~= _G.next(tItem) then
+        local tPrize = {}
+        for nID, nNum in pairs(tItem) do
+            table.insert(tPrize, {nID, nNum})
+        end
+
+        BagLogic.addItemList(human, tPrize, "CommonActCharge")
+        CommonActCharge_Query(human)
+        YunYingLogic.sendBanner(human)
+        local config = AbsActExcel.absActivity[COMMONACTCHARGEABSID]
+        YunYingLogic.sendGroupUpdate(YYInfo[COMMONACTCHARGEABSID], human, config.panelID)
+    end
+end
+
+----------------------------------------- 外部调用 -------------------------------------
+function isRed(human)
+    local state, nEndTime, nOpenTime = AbsActLogic.isStarted(human, COMMONACTCHARGEABSID)
+    if not state then
+        return false
+    end
+
+    CheckAndCreateDB(human)
+
+    local tConf = CommonActCharge_GetCof()
+    for nID, v in ipairs(tConf) do
+        local nState = CommonActCharge_GetDBPrizeStatus(human, nID)
+        if nState == CommonDefine.COMMON_PRIZE_STATE_CANGET then
+            return true
+        end
+    end
+
+    return false
+end
+
+function isOpen(human, YYInfo, funcConfig)
+    local state, endTime, startTime = AbsActLogic.isStarted(human, funcConfig and funcConfig.funcID or COMMONACTCHARGEABSID)
+    if not state then
+        print("[CommonActCharge_isOpen] 当前活动未开启")
+        return 
+    end
+    print("[CommonActCharge__isOpen] 进入判断 endTime = "..endTime.." startTime = "..startTime)
+    return true, endTime, startTime
+end
+
+function isActive(human, YYInfo, funcConfig)
+    return not isOpen(human, YYInfo, funcConfig)
+end
+
+function onCharge(human, price, funcID, buyID)
+   local state, endTime, startTime = AbsActLogic.isStarted(human, COMMONACTCHARGEABSID)
+    if not state then 
+        return 
+    end
+
+    CheckAndCreateDB(human)
+
+    local tConf = CommonActCharge_GetCof()
+    local bQuery = false
+
+    local nNewChareNum = CommonActCharge_GetDBDayCharge(human)
+    nNewChareNum = nNewChareNum + price
+    
+    for nID, v in ipairs(tConf) do
+        local nStatus = CommonActCharge_GetDBPrizeStatus(human, nID)
+        if nStatus == CommonDefine.COMMON_PRIZE_STATE_NOGET and nNewChareNum >= v.nMoney then
+            CommonActCharge_SetDBPrizeStatus(human, nID, CommonDefine.COMMON_PRIZE_STATE_CANGET)
+            bQuery = true
+        end
+    end
+
+    CommonActCharge_SetDBDayCharge(human, price)
+
+    if true == bQuery then
+        CommonActCharge_Query(human)
+        YunYingLogic.sendBanner(human)
+        local config = AbsActExcel.absActivity[COMMONACTCHARGEABSID]
+        YunYingLogic.sendGroupUpdate(YYInfo[COMMONACTCHARGEABSID], human, config.panelID)
+    end
+end
+
+function onLogin(human)
+   local state, endTime, startTime = AbsActLogic.isStarted(human, COMMONACTCHARGEABSID)
+    if not state then 
+        return 
+    end
+
+    CheckAndCreateDB(human)
+    if not human.db.absAct[COMMONACTCHARGEABSID].IsAddCharge then
+        human.db.absAct[COMMONACTCHARGEABSID].IsAddCharge = true
+        if human.db.topupAcountDaily and human.db.topupAcountDaily > 0 then
+            onCharge(human, human.db.topupAcountDaily)
+        end
+    end
+end

+ 280 - 0
script/module/absAct/CommonActFindTreasure.lua

@@ -0,0 +1,280 @@
+--------------------------------
+-- 文件名       :   CommonActCharge.lua
+-- 文件说明     :   通用节日活动-连充豪礼
+-- 创建时间     :   2025/09
+-- 创建人       :   FC
+--------------------------------
+
+local Msg = require("core.Msg")
+local Grid = require("bag.Grid")
+local BagLogic = require("bag.BagLogic")
+local AbsActLogic = require("absAct.AbsActLogic")
+local Broadcast = require("broadcast.Broadcast")
+local Lang = require("common.Lang")
+local Config = require("excel.commonact").findprize
+local CommonDefine = require("common.CommonDefine")
+local Util = require("common.Util")
+local YunYingLogic = require("yunying.YunYingLogic")
+local AbsActExcel = require("excel.absAct")
+
+local COMMONACTFINDABSID = 7504        -- 对应ABS活动ID
+local COMMONACTFINDUSEITEM = 1243      -- 寻宝使用道具ID
+
+local COMMONACTDOMAXNUM = nil    -- 最大抽取保底次数
+
+----------------------------------------- 内部处理开始 -------------------------------------
+local function ComActFindTreasure_CreateDB(human)
+    if not human.db.absAct[COMMONACTFINDABSID] then
+        human.db.absAct[COMMONACTFINDABSID] = {}
+    end
+    
+    human.db.absAct[COMMONACTFINDABSID].tExtract = {
+        nFreeNum = 1,          -- 免费次数
+        nFreeRefreshTime = os.time(),   -- 免费刷新次数
+        nAllNum = 0,           -- 总次数
+    }
+end
+
+-- 检测并创建DB数据
+local function ComActFindTreasure_CheckAndCreateDB(human)
+    if not human.db.absAct[COMMONACTFINDABSID] or not human.db.absAct[COMMONACTFINDABSID].tExtract then
+        ComActFindTreasure_CreateDB(human)
+    end
+end
+
+local function ComActFindTreasure_GetDoMaxNum()
+    if nil ~= COMMONACTDOMAXNUM then
+        return COMMONACTDOMAXNUM
+    end
+
+    for _, v in ipairs(Config) do
+        if not COMMONACTDOMAXNUM then
+           COMMONACTDOMAXNUM = v.nNeedNum
+        else
+            COMMONACTDOMAXNUM = math.max(COMMONACTDOMAXNUM, v.nNeedNum)
+        end
+    end
+
+    return COMMONACTDOMAXNUM
+end
+
+-- 获取免费次数
+local function ComActFindTreasure_GetDBFreeNum(human)
+    return human.db.absAct[COMMONACTFINDABSID].tExtract.nFreeNum
+end
+
+-- 设置免费次数
+local function ComActFindTreasure_SetDBFreeNum(human, nNum)
+    human.db.absAct[COMMONACTFINDABSID].tExtract.nFreeNum = nNum
+end
+
+-- 获取刷新时间
+local function ComActFindTreasure_GetDBFreeRefreshTime(human)
+    return human.db.absAct[COMMONACTFINDABSID].tExtract.nFreeRefreshTime
+end
+
+-- 设置刷新时间
+local function ComActFindTreasure_SetDBFreeRefreshTime(human, nTime)
+    human.db.absAct[COMMONACTFINDABSID].tExtract.nFreeRefreshTime = nTime
+end
+
+-- 获取总次数
+local function ComActFindTreasure_GetDBAllNum(human)
+    return human.db.absAct[COMMONACTFINDABSID].tExtract.nAllNum
+end
+
+-- 设置总次数
+local function ComActFindTreasure_SetDBAllNum(human, nNum)
+    human.db.absAct[COMMONACTFINDABSID].tExtract.nAllNum = nNum
+end
+
+-- 抽取动作
+local function ComActFindTreasure_FindDo(human, nDoNum)
+    local nAllNum = ComActFindTreasure_GetDBAllNum(human)
+    local nMaxDoNum = ComActFindTreasure_GetDoMaxNum()
+
+    local nAllWeight, tItemInfo = 0, {}
+    for _, v in ipairs(Config) do
+        nAllWeight = nAllWeight + v.nWeight
+        local bBaoDi = false
+        if nMaxDoNum == v.nNeedNum then
+            bBaoDi = true
+        end
+
+        table.insert(tItemInfo, {nWeight = nAllWeight, tPrize = v.tPrize, bBaoDi = bBaoDi});
+    end
+    
+    local tGoodsInfo = {}
+    for i = 1, nDoNum, 1 do
+        local bUseBaoDi = false
+        nAllNum = nAllNum + 1
+        if nAllNum >= nMaxDoNum then
+            nAllNum = 0
+            bUseBaoDi = true
+        end
+
+        local nRandWeight = math.random(1, nAllWeight)
+        for _, v in ipairs(tItemInfo) do
+            if true == bUseBaoDi then
+                if v.bBaoDi == true then
+                    if not tGoodsInfo[v.tPrize[1]] then
+                        tGoodsInfo[v.tPrize[1]] = 0
+                    end
+    
+                    tGoodsInfo[v.tPrize[1]] = tGoodsInfo[v.tPrize[1]]  + v.tPrize[2]
+                    break
+                end
+            else
+                if nRandWeight <= v.nWeight then
+                    if not tGoodsInfo[v.tPrize[1]] then
+                        tGoodsInfo[v.tPrize[1]] = 0
+                    end
+
+                    tGoodsInfo[v.tPrize[1]] = tGoodsInfo[v.tPrize[1]]  + v.tPrize[2]
+                    if v.bBaoDi == true then
+                        nAllNum = 0
+                    end
+
+                    break
+                end
+            end
+        end
+    end
+
+    ComActFindTreasure_SetDBAllNum(human, nAllNum)
+    return true, tGoodsInfo
+end
+
+----------------------------------------- 内部处理结束 -------------------------------------
+function isOpen(human, YYInfo, funcConfig)
+    local state, endTime, startTime = AbsActLogic.isStarted(human, funcConfig.funcID and funcConfig.funcID or COMMONACTFINDABSID)
+    if not state then
+        print("[CommonActFindTreasure_isOpen] 当前活动未开启")
+        return
+    end
+    
+    print("[CommonActFindTreasure_isOpen] 进入判断 endTime = "..endTime.." startTime = "..startTime)
+    return state, endTime, startTime
+end
+
+function isActive(human, YYInfo, funcConfig)
+    local state = isOpen(human, YYInfo, funcConfig)
+    return not state
+end
+
+function isRed(human)
+    local state, nEndTime, nOpenTime = AbsActLogic.isStarted(human, COMMONACTFINDABSID)
+    if not state then
+        return false
+    end
+
+    ComActFindTreasure_CheckAndCreateDB(human)
+
+    local nFreeNum  = ComActFindTreasure_GetDBFreeNum(human)
+    return nFreeNum > 0
+end
+
+function onZero(human, funcID)
+    local state, nEndTime, nOpenTime = AbsActLogic.isStarted(human, COMMONACTFINDABSID)
+    if not state then
+        return
+    end
+
+    ComActFindTreasure_SetDBFreeNum(human, 1)
+    ComActFindTreasure_SetDBFreeRefreshTime(human, os.time())
+end
+
+function onLogin(human, funcID)
+    local state, nEndTime, nOpenTime = AbsActLogic.isStarted(human, COMMONACTFINDABSID)
+    if not state then
+        return
+    end
+
+    ComActFindTreasure_CheckAndCreateDB(human)
+
+    local nFreeRefreshTime = ComActFindTreasure_GetDBFreeRefreshTime(human)
+    if true ~= Util.isSameDayByTimes(nFreeRefreshTime, os.time()) then
+        ComActFindTreasure_SetDBFreeNum(human,  1)
+        ComActFindTreasure_SetDBFreeRefreshTime(human, os.time())
+    end
+end
+
+------------------------------------ 客户端请求处理开始 ---------------------------------
+function CommonActFindTreasure_Query(human)
+    local nStatus = AbsActLogic.isStarted(human, COMMONACTFINDABSID)
+    if not nStatus then
+        return
+    end
+
+    ComActFindTreasure_CheckAndCreateDB(human)
+
+    local msgRet = Msg.gc.GC_ABS_FESTIVAL_SEVENDAY_CARD_QUERY
+    msgRet.nFreeNum = ComActFindTreasure_GetDBFreeNum(human)
+    msgRet.nNowNum = ComActFindTreasure_GetDBAllNum(human)
+    msgRet.nMaxNum = ComActFindTreasure_GetDoMaxNum()
+    Grid.makeItem(msgRet.tUseItem, COMMONACTFINDUSEITEM, 1)
+
+    msgRet.tPrize[0] = #Config
+    for index, v in ipairs(Config) do
+        local tData = msgRet.tPrize[index]
+        tData.nID = index
+        tData.nRare = v.nRare
+      
+        Grid.makeItem(tData.tPrize, v.tPrize[1], v.tPrize[2])
+    end
+
+    Msg.send(msgRet, human.fd)
+end
+
+function CommonActFindTreasure_Do(human, nType)
+    local nStatus = AbsActLogic.isStarted(human, COMMONACTFINDABSID)
+    if not nStatus then
+        return
+    end
+
+    if 1 ~= nType and 2 ~= nType then
+        print("[CommonActFindTreasure_Do] 上传的类型不正确 nType = "..nType)
+        return
+    end
+
+    local nUseNum = 1 == nType and 1 or 10
+
+    ComActFindTreasure_CheckAndCreateDB(human)
+
+    local nFreeNum = ComActFindTreasure_GetDBFreeNum(human)
+    local nDelNum = nUseNum - nFreeNum
+    if nDelNum < 0 then
+        nDelNum = 0
+    end
+    if nDelNum > 0 and not BagLogic.checkItemCnt(human, COMMONACTFINDUSEITEM, nDelNum) then
+        print("[CommonActFindTreasure_Do] 消耗的物品不足 nFreeNum = "..nFreeNum.." nDelNum = "..nDelNum)
+        return
+    end
+
+    local bRet, tItem = ComActFindTreasure_FindDo(human, nUseNum)
+    if false == bRet then
+        print("[CommonActFindTreasure_Do] 抽取动作执行失败")
+        return
+    end
+
+    if nFreeNum > 0 then
+        nFreeNum = nFreeNum >= nUseNum and nFreeNum - nUseNum or 0
+        ComActFindTreasure_SetDBFreeNum(human, nFreeNum)
+    end
+
+    BagLogic.delItem(human, COMMONACTFINDUSEITEM, nDelNum, "CommonActFindTreasure")
+
+    local tGoods = {}
+    for nID, nNum in pairs(tItem) do
+        table.insert(tGoods, {nID, nNum})
+    end
+
+    if nil ~= _G.next(tGoods) then
+       BagLogic.addItemList(human, tGoods, "CommonActFindTreasure")
+       CommonActFindTreasure_Query(human)
+    end
+
+    YunYingLogic.sendBanner(human)
+    local config = AbsActExcel.absActivity[COMMONACTFINDABSID]
+    YunYingLogic.sendGroupUpdate(YYInfo[COMMONACTFINDABSID], human, config.panelID)
+end

+ 147 - 0
script/module/absAct/CommonActShop.lua

@@ -0,0 +1,147 @@
+--新商业化活动3—天选兑换
+--db
+--[=[
+    human.db.absAct[id] = {
+        buyRecord = {
+            [1] = 2, --key是道具在配置中的id, value是已经购买次数
+            [2] = 1,
+        }
+    }
+]=]--
+
+local Util = require("common.Util")
+local Msg = require("core.Msg")
+local Grid = require("bag.Grid")
+local BagLogic = require("bag.BagLogic")
+local AbsActLogic = require("absAct.AbsActLogic")
+local Broadcast = require("broadcast.Broadcast")
+local Lang = require("common.Lang")
+local Config = require("excel.commonact").store
+
+local LOGTAG = "CommonActShop" --日志标识
+
+local COMMONACTSHOPABSID = 7502        -- 对应ABS活动ID
+
+local function CreateDB(human)
+    if not human.db.absAct[COMMONACTSHOPABSID] then
+        human.db.absAct[COMMONACTSHOPABSID] = {}
+    end
+
+    if not human.db.absAct[COMMONACTSHOPABSID].buyRecord then
+        human.db.absAct[COMMONACTSHOPABSID].buyRecord = {}
+    end
+
+    for index, v in ipairs(Config) do
+        human.db.absAct[COMMONACTSHOPABSID].buyRecord[index] = 0
+    end
+end
+
+local function CheckAndCreateDB(human)
+    if not human.db.absAct[COMMONACTSHOPABSID] or not human.db.absAct[COMMONACTSHOPABSID].buyRecord then
+        CreateDB(human)
+    end
+end
+
+function isOpen(human, YYInfo, funcConfig)
+    local state, endTime, startTime = AbsActLogic.isStarted(human, funcConfig.funcID and funcConfig.funcID or COMMONACTSHOPABSID)
+     if not state then
+        print("[CommonActShop_isOpen] 当前活动未开启")
+        return
+    end
+    
+    print("[CommonActShop_isOpen] 进入判断 endTime = "..endTime.." startTime = "..startTime)
+    return state, endTime, startTime
+end
+
+function isActive(human, YYInfo, funcConfig)
+    local state = isOpen(human, YYInfo, funcConfig)
+    return not state
+end
+
+--查询
+function CommonActShop_Query(human)
+    CheckAndCreateDB(human)
+
+    local state = AbsActLogic.isStarted(human, COMMONACTSHOPABSID)
+    if not state then
+        print("[CommonActShop_Query] 当前活动未开启")
+        return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
+    end
+
+    local actData = human.db.absAct[COMMONACTSHOPABSID]
+    if not actData then
+        print("[CommonActShop_Query] 不存在对应的活动数据")
+        return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
+    end
+
+    print("[CommonActShop_Query] 正常进入")
+    local buyRecord = actData.buyRecord
+    local msgRet = Msg.gc.GC_ABS_FESTIVAL_SHOP_QUERY
+
+    local itemVec = msgRet.tGoodInfo
+    itemVec[0] = #Config
+
+    for k,v in ipairs(Config) do
+        local singleItem = itemVec[k]
+        local tempConfig = v
+        Grid.makeItem(singleItem.itemData, tempConfig.item[1], tempConfig.item[2])
+        singleItem.itemIndex = k
+        Grid.makeItem(singleItem.needItem, tempConfig.currencyInfo[1], tempConfig.currencyInfo[2])
+        singleItem.maxCanBuy = tempConfig.maxBuyCnt
+        singleItem.nowBuy = buyRecord and buyRecord[k] or 0
+        singleItem.zhekou  = 0
+        singleItem.order  = 0
+        singleItem.needVipLv = 0
+        singleItem.rare = 0
+        singleItem.limitType = 1
+        singleItem.bCanChose = 0
+        singleItem.bChose = 0
+    end
+
+    Msg.send(msgRet, human.fd)
+end
+
+--购买商品
+function CommonActShop_Buy(human, itemIdx, buyCnt)
+    local state = AbsActLogic.isStarted(human, COMMONACTSHOPABSID)
+    if not state then
+        return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
+    end
+
+    local actData = human.db.absAct[COMMONACTSHOPABSID]
+    if not actData then
+        return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
+    end
+
+    local itemCfg = Config[itemIdx]
+    if not itemCfg or buyCnt <= 0 then
+        print("[CommonActShop_Buy] 不正确的数据 itemIdx = "..itemIdx.." buyCnt = "..buyCnt)
+        return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
+    end
+
+    local buyRecord = actData.buyRecord
+    if buyRecord and buyRecord[itemIdx] then
+        if buyRecord[itemIdx] + buyCnt > itemCfg.maxBuyCnt then
+            return Broadcast.sendErr(human, Lang.COMMON_BUY_NUM_NOT_ENOUGH)
+        end
+    end
+
+    local currencyInfo = itemCfg.currencyInfo
+    local cnt = currencyInfo[2] * buyCnt
+    if BagLogic.getItemCnt(human, currencyInfo[1]) < cnt then
+        return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
+    end
+    BagLogic.delItem(human, currencyInfo[1], cnt, LOGTAG)
+
+    --更新数据
+    buyRecord = buyRecord or {}
+    buyRecord[itemIdx] = (buyRecord[itemIdx] or 0) + buyCnt
+    actData.buyRecord = buyRecord
+
+    --发放奖励
+    local itemInfo = itemCfg.item
+    BagLogic.addItemList(human, {{itemInfo[1], itemInfo[2] * buyCnt}}, LOGTAG)
+
+    --下发数据
+    CommonActShop_Query(human)
+end

+ 1 - 1
script/module/absAct/CycleHeroSendGift.lua

@@ -62,7 +62,7 @@ local function checkGridState(human, actId, nowBuyId)
     end
 
     local gridData = actData.gridData
-    local nowIdx = gridData.nowIdx
+    local nowIdx = gridData and gridData.nowIdx or -1
 
     local gridCfg = heroSendGiftCfg[nowIdx]
     if not gridCfg then

+ 52 - 6
script/module/absAct/CycleMakeFood.lua

@@ -5,6 +5,7 @@
     human.db.absAct[id] = {
             nowFoodIdx = nil,
             fiveStarFoodArray = nil, { {配置idx, 玩家选择的食材(字符串)}  }    -- 玩家合成的五星级食物列表,活动结束也不删除
+            isTenTimes = nil,   -- 新增需求, 是否选择了10倍消耗, 为true表示选择了10倍消耗, 为其他值则表示没有
         }
 ]=]--
 
@@ -60,6 +61,22 @@ local function calcSameValCnt(t, val)
     return cnt
 end
 
+local function isRepeatRecord(human, actId, nowFoodIdx)
+    local actData = getActData(human, actId)
+    if not actData then
+        return false
+    end
+
+    for _, recordInfo in ipairs(actData.fiveStarFoodArray or {}) do
+        if recordInfo[1] == nowFoodIdx then
+            return true
+        end
+    end
+
+    return false
+end
+
+
 
 function isOpen(human, YYInfo, funcConfig)
     local state, endTime, startTime = CycleActivityLogic.isStarted(human, funcConfig.funcID)
@@ -86,9 +103,16 @@ function Query(human, actId)
 
     local msgRet = Msg.gc.GC_CYCLMAKEFOOD_QUERY
     local foodCfg = makeFoodCfg[nowFoodIdx]
+    msgRet.isTenTimes = 0
+
+    local mul = 1
+    if actData.isTenTimes then
+        mul = 10
+        msgRet.isTenTimes = 1
+    end
 
     msgRet.tagetFoodName = foodCfg.targetFoodName
-    Grid.makeItem(msgRet.itemInfo, actVariableCfg.va1[1], actVariableCfg.va1[2])
+    Grid.makeItem(msgRet.itemInfo, actVariableCfg.va1[1], actVariableCfg.va1[2] * mul)
     local foodList = msgRet.foodList
 
     for k,v in ipairs(foodCfg.iconList) do
@@ -132,12 +156,17 @@ function MakeFood(human, actId, foodStr)
     end
 
 
+    local mul = 1
+    if actData.isTenTimes then
+        mul = 10
+    end
+
     -- 消耗道具检测
     local itemId, itemCnt = actVariableCfg.va1[1], actVariableCfg.va1[2]
-    if BagLogic.getItemCnt(human, itemId) < itemCnt then
+    if BagLogic.getItemCnt(human, itemId) < itemCnt * mul then
         return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
     end
-    BagLogic.delItem(human, itemId, itemCnt, LOGTAG)
+    BagLogic.delItem(human, itemId, itemCnt*mul, LOGTAG)
 
 
     local msgRet = Msg.gc.GC_CYCLMAKEFOOD_MAKEFOOD
@@ -152,7 +181,7 @@ function MakeFood(human, actId, foodStr)
     local foodCfg = makeFoodCfg[nowFoodIdx]
 
     -- 五星级食物制作成功则保存记录
-    if rightNum >= 5 then
+    if rightNum >= 5 and not isRepeatRecord(human, actId, nowFoodIdx) then
         update5StarFoodArray(human, actId, nowFoodIdx, foodStr)
     end
 
@@ -163,10 +192,10 @@ function MakeFood(human, actId, foodStr)
     for idx, itemCfg in ipairs(foodCfg.reward[rightNum] or {}) do
         -- len = len + 1
         -- rewardList[len] = { itemCfg[1], itemCfg[2] }
-        BagLogic.addItem(human, itemCfg[1], itemCfg[2], LOGTAG)
+        BagLogic.addItem(human, itemCfg[1], itemCfg[2] * mul, LOGTAG)
 
         itemArray[0] = idx
-        Grid.makeItem(itemArray[idx], itemCfg[1], itemCfg[2])
+        Grid.makeItem(itemArray[idx], itemCfg[1], itemCfg[2] * mul)
     end
     -- BagLogic.addItemList(human, rewardList, LOGTAG)
 
@@ -234,4 +263,21 @@ function Get5StarFoodArray(human, actId)
         Msg.send(msgRet, human.fd)
     end
 
+end
+
+function SelectTenTimes(human, actId, opType)
+    local actData = getActData(human, actId)
+    if not actData then
+        return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
+    end
+
+    if opType == 0 then
+        actData.isTenTimes = false
+    elseif opType == 1 then
+        actData.isTenTimes = true
+    else
+        return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
+    end
+
+    Query(human, actId)
 end

+ 29 - 6
script/module/absAct/CycleSevenDayTask.lua

@@ -31,6 +31,7 @@ local TriggerLogic = require("trigger.TriggerLogic")
 local CycleActivityLogic = require("yunying.CycleActivity")
 local actVariableCfg = require("excel.commercializationActivity").variable[1]
 local sevenDayTaskCfg = require("excel.commercializationActivity").sevenDayTask
+local Log = require("common.Log")
 
 
 -- 本活动日志标识
@@ -46,7 +47,21 @@ local function getActBaseInfo(human, actId)
     return state, endTime, startTime
 end
 
+local function initData(human, actId)
+    local state, realEndTime = isOpen(human)
+    if not state then
+        return
+    end
+
+    human.db.absAct[actId] = human.db.absAct[actId] or {}
+    human.db.absAct[actId].finish = realEndTime
+end
+
+
 local function getActData(human, actId)
+    if not human.db.absAct[actId] then
+        initData(human, actId)
+    end
     return human.db.absAct[actId]
 end
 
@@ -173,7 +188,7 @@ local function subscribeEvents(human, actId)
 
     for taskId, taskCfg in ipairs(sevenDayTaskCfg)  do
         if not registerTypeList[taskCfg.eventType] and (not taskList[taskId] or taskList[taskId].progress < taskCfg.condValue) then
-            TriggerLogic.SubscribeEvent(taskCfg.eventType, human.db._id, EventCBFunc)
+            TriggerLogic.SubscribeEvent(taskCfg.eventType, human.db._id, TaskActEventCBFunc)
             registerTypeList[taskCfg.eventType] = 1
         end
     end
@@ -249,7 +264,7 @@ end
 
 
 --事件处理函数
-function EventCBFunc(eventType, uuid, nValue1, nValue2)
+function TaskActEventCBFunc(eventType, uuid, nValue1, nValue2)
     local human = ObjHuman.onlineUuid[uuid]
     if not human then
         return
@@ -348,21 +363,29 @@ function onLogin(human, funcID)
         return
     end
 
-    if isCompleteAllTask(human, funcID) then
+    if isCompleteAllTask(human, funcID) or human.sevenDayTaskRegister then
         return
     end
 
     subscribeEvents(human, funcID)
+
+    human.sevenDayTaskRegister = true
 end
 
 function updateDaily(human, funcID)
     if not isOpen(human) then
+        local logStr = string.format("CycleSevenDayTask Act is cannot Open, now: %d, playweNewUniqueTag: %s", os.time(), human.db.newUniqueTag)
+        Log.write(Log.LOGID_OSS_COMMON_ACT, logStr)
         return
     end
 
-    local actData = getActData(human, ACTID)
-    if not actData then
-        return
+    -- local actData = getActData(human, ACTID)
+    -- if not actData then
+    --     return
+    -- end
+    if not human.sevenDayTaskRegister and not isCompleteAllTask(human, ACTID) then
+        subscribeEvents(human, funcID)
+        human.sevenDayTaskRegister = true
     end
 
     local actOpenDayIdx = getActOPenDayIdx(human)

+ 12 - 7
script/module/absAct/DoubleChargeLogic.lua

@@ -1,6 +1,6 @@
 --[[
   human.db.absAct[id] = {
-            [buyID] = cnt       buyID ��Ӧ�޹�����
+            [buyID] = cnt       buyID 对应限购次数
         }
 
 ]]
@@ -27,7 +27,7 @@ function isActive(human, YYInfo, funcConfig)
 end
 
 
--- ���ʣ��˫������
+-- 获得剩余双倍次数
 function getDoubleCnt(human, funcID, buyID)
     local config = AbsActExcel.absActivity[funcID]
     if not config then return 0 end
@@ -45,7 +45,7 @@ function getDoubleCnt(human, funcID, buyID)
 
     local buyItemConfig = BuyExcel.buy[buyID]
 
-    -- ���dz�ֵ���򷵻�
+   -- 不是充值,则返回
     if buyItemConfig.cmd ~= "topup" then
         return 0
     end
@@ -55,7 +55,7 @@ function getDoubleCnt(human, funcID, buyID)
     return absAct.buyID[buyID]
 end
 
--- 0������
+-- 0点重置
 function updateDaily(human, funcID)
     local state, endTime, starTime = AbsActLogic.isStarted(human, funcID)
     if not state then return end
@@ -66,7 +66,7 @@ function updateDaily(human, funcID)
     local doubleConfig = AbsActExcel.doubleCharge[config.actId]
     if not doubleConfig then return 0 end
 
-    -- ��0��������Ϊ2��˫��
+     -- 过0点则设置为2次双倍
     AbsActLogic.checkAbsActClean(human, funcID)
     local absAct = human.db.absAct[funcID]
 
@@ -76,8 +76,8 @@ function updateDaily(human, funcID)
     end
 end
 
--- �ص�
--- ��yunyinglogic ������ã��������жϻ�Ƿ���
+-- 回调
+-- 从yunyinglogic 里面调用,故无需判断活动是否开起
 -- 
 function buyCall(human,id,buyID)
     local absAct = human.db.absAct[id]
@@ -85,3 +85,8 @@ function buyCall(human,id,buyID)
     absAct.buyID[buyID] = absAct.buyID[buyID] or 4
     absAct.buyID[buyID] = absAct.buyID[buyID] - 1
 end
+
+-- function GetRemainNum(human, nBuyID)
+--     -- 钻石一直可以购买
+--     return 1
+-- end

+ 11 - 9
script/module/absAct/FestivalSevenDayCardLogic.lua

@@ -268,14 +268,6 @@ end
 
 function onLogin(human, funcID)
     local tAbsAct = human.db.absAct[SEVENDAYCARD_ID]
-    if tAbsAct then
-        if tAbsAct.nStatus then
-            print("[onLogin] nStatus = \n", tAbsAct.nStatus) 
-        end
-    else
-        print("[onLogin] 不存在对应的数据了")
-    end
-
     if tAbsAct and SEVENDAYCARD_STAUS_BUY == tAbsAct.nStatus then
         local nDiffDay = Util.diffDay(tAbsAct.nBuyTime)
         local nCheckDay = nDiffDay + 1 >= SEVENDAYCARD_TOTALDAY and SEVENDAYCARD_TOTALDAY or nDiffDay + 1
@@ -302,4 +294,14 @@ function onLogin(human, funcID)
             end
         end
     end
-end
+end
+
+-- function GetRemainNum(human, nBuyID)
+--     local tConfig = AbsActExcel.festvialSevenDayCard
+--     local absAct = human.db.absAct[SEVENDAYCARD_ID]
+--     if not absAct then
+--         return 0
+--     end
+
+--     return SEVENDAYCARD_STAUS_NOBUY == absAct.nStatus and 1 or 0
+-- end

+ 95 - 2
script/module/absAct/Handler.lua

@@ -42,8 +42,14 @@ local CycleSevenDayTask = require("absAct.CycleSevenDayTask")
 local CycleHeroSendGift = require("absAct.CycleHeroSendGift")
 local CycleBreakThrough = require("absAct.CycleBreakThrough")
 local CycleMakeFood = require("absAct.CycleMakeFood")
-
-
+local BusThreeActGrandGift = require("absAct.BusThreeActGrandGift")
+local BusThreeActDisStore = require("absAct.BusThreeActDiscountStore")
+local BusThreeActTask = require("absAct.BusThreeActTask")
+local BusThreeActDice = require("absAct.BusThreeActDice")
+local CommonActBoss = require("absAct.CommonActBoss")
+local CommonActShop = require("absAct.CommonActShop")
+local CommonActCharge = require("absAct.CommonActCharge")
+local CommonActFindTreasure = require("absAct.CommonActFindTreasure")
 
 function CG_ABS_ACT_DETAIL_QUERY(human, msg)
     AbsActLogic.actDetailQuery(human,msg.id)
@@ -404,4 +410,91 @@ end
 
 function CG_CYCLMAKEFOOD_GET_5STARfOODLIST(human, msg)
     CycleMakeFood.Get5StarFoodArray(human, msg.actId)
+end
+
+function CG_CYCLMAKEFOOD_SELECT_MUL(human, msg)
+    CycleMakeFood.SelectTenTimes(human, msg.actId, msg.opType)
+end
+
+-----------------------------------------------------新商业化活动3 — 天选豪礼--------------------------------------------------
+function CG_NEW_BUSTHREEACT_GRANDGIFT_QUERY(human, msg)
+    BusThreeActGrandGift.BusThreeGrandGift_Query(human)
+end
+
+function CG_NEW_BUSTHREEACT_GRANDGIFT_GET(human, msg)
+    BusThreeActGrandGift.BusThreeGrandGift_Get(human)
+end
+
+-----------------------------------------------------新商业化活动3 — 特价商店--------------------------------------------------
+function CG_NEW_BUSTHREEACT_DISQUERY(human, msg)
+    BusThreeActDisStore.Query(human)
+end
+
+function CG_NEW_BUSTHREEACT_DISBUY(human, msg)
+    BusThreeActDisStore.BuyItem(human, msg.id, msg.idx, msg.buyCnt)
+end
+
+-----------------------------------------------------新商业化活动3 — 任务 --------------------------------------------------
+function CG_NEW_BUSTHREEACT_TASKQUERY(human, msg)
+    print("[CG_NEW_BUSTHREEACT_TASKQUERY] 玩家请求任务信息 name = "..human.db.name)
+    BusThreeActTask.BusThreeActTask_QueryTask(human, msg.nDay)
+end
+
+function CG_NEW_BUSTHREEACT_GETTASKPRIZE(human, msg)
+    BusThreeActTask.BusThreeActTask_GetTaskPrize(human, msg.nDay)
+end
+
+function CG_NEW_BUSTHREEACT_TASKPOINTQUERY(human, msg)
+    print("[CG_NEW_BUSTHREEACT_TASKPOINTQUERY] 玩家请求任务积分信息 name = "..human.db.name)
+    BusThreeActTask.BusThreeActTask_QueryTaskPoint(human)
+end
+
+function CG_NEW_BUSTHREEACT_GETTASKPOINTPRIZE(human, msg)
+    BusThreeActTask.BusThreeActTask_GetTaskPointPrize(human)
+end
+
+-----------------------------------------------------新商业化活动3 — 天选骰子 --------------------------------------------------
+function CG_NEW_BUSTHREEACT_DICEDO(human, msg)
+    BusThreeActDice.BusThreeActDice_DO(human, msg.nNum)
+end
+
+
+----------------------------------------------------通用节日活动 — 个人BOSS --------------------------------------------------
+function CG_ABS_FESTIVAL_BOSS_QUERY(human, msg)
+    CommonActBoss.CommonActBoss_Query(human)
+end
+
+function CG_ABS_FESTIVAL_BOSS_REWARD(human, msg)
+    CommonActBoss.CommonActBoss_QueryPrize(human)
+end
+
+function CG_ABS_FESTIVAL_BOSS_GET(human, msg)
+    CommonActBoss.CommonActBoss_GetPrize(human)
+end
+
+----------------------------------------------------通用节日活动 — 商店 --------------------------------------------------
+function CG_ABS_FESTIVAL_SHOP_QUERY(human, msg)
+    CommonActShop.CommonActShop_Query(human)
+end
+
+function CG_ABS_FESTIVAL_SHOP_BUY(human, msg)
+    CommonActShop.CommonActShop_Buy(human, msg.nID, msg.nCnt)
+end
+
+----------------------------------------------------通用节日活动 — 充值 --------------------------------------------------
+function CG_ABS_FESTIVAL_RECHARGE_QUERY(human, msg)
+    CommonActCharge.CommonActCharge_Query(human)
+end
+
+function CG_ABS_FESTIVAL_RECHARGE_GET(human, msg)
+    CommonActCharge.CommonActCharge_Get(human, msg.nID)
+end
+
+----------------------------------------------------通用节日活动 — 限时寻宝 --------------------------------------------------
+function CG_ABS_FESTIVAL_SEVENDAY_CARD_QUERY(human, msg)
+    CommonActFindTreasure.CommonActFindTreasure_Query(human)
+end
+
+function CG_ABS_FESTIVAL_SEVENDAY_CARD_DO(human, msg)
+    CommonActFindTreasure.CommonActFindTreasure_Do(human, msg.nType)
 end

+ 13 - 0
script/module/absAct/HeroGrowUp.lua

@@ -1179,3 +1179,16 @@ function actLoop()
         return
     end
 end
+
+-- function GetRemainNum(human, nBuyID)
+-- 	local actStartTime,actEndTime, groupID = getActStartTime()
+-- 	local lvConfigs = getLvConfigs(groupID)
+-- 	if not actStartTime then return 0 end
+
+-- 	local isBuy = isBuyKing(human)
+-- 	if isBuy == 1 then 
+-- 		return 0
+-- 	else
+-- 		return 1
+-- 	end
+-- end

+ 26 - 2
script/module/absAct/MangHeLogic.lua

@@ -26,6 +26,8 @@ MANGHE_MR_STATUS_2 = 2 --已领取
 MANGHE_RARE_MAX = nil   -- 权重和
 MANGHE_RARE_MUM = nil   -- 保底权重和
 
+local MANGHE_ABS_ID = 2001
+
 local function initMrDb(human, id, mrId)
    local absAct = human.db.absAct[id]
    if not absAct then return end
@@ -332,7 +334,7 @@ function mrGet(human, mrId)
 end
 
 -- 盲盒礼包 购买
-function mangHeGift(human, id, buyConf, isFirst, cnt)
+function mangHeGift(human, id, buyConf, isFirst, cnt, buyNum)
     local state = AbsActLogic.isStarted(human, id)
     if not state then return end
     
@@ -343,6 +345,17 @@ function mangHeGift(human, id, buyConf, isFirst, cnt)
         return 
     end
 
+    -- if buyCnt + buyNum >= config.cnt  then
+    --     return
+    -- end
+    
+    -- human.db.absAct[id].buyCnt = buyCnt + buyNum
+    -- local tItemList = {}
+    -- for index, v in ipairs(config.reward) do
+    --     table.insert(tItemList, {v[1], v[2]*buyNum})
+    -- end
+    -- BagLogic.addItemList(human, tItemList, "abs_manghe")
+
     human.db.absAct[id].buyCnt = buyCnt + 1
     BagLogic.addItemList(human, config.reward, "abs_manghe")
     query(human, id)
@@ -458,4 +471,15 @@ end
 
 function isOpen(human, YYInfo, funcConfig)
     return AbsActLogic.isStarted(human, funcConfig.funcID)
-end
+end
+
+-- function GetRemainNum(human, nBuyID)
+--     local config = AbsActExcel.mangHeGift[1]
+--     if config.buyID ~= nBuyID then
+--         return 0
+--     end
+
+--     AbsActLogic.checkAbsActClean(human, MANGHE_ABS_ID)
+--     local buyCnt = human.db.absAct[MANGHE_ABS_ID].buyCnt and human.db.absAct[MANGHE_ABS_ID].buyCnt or 0
+--     return buyCnt < config.cnt and (config.cnt - buyCnt) or 0
+-- end

+ 36 - 2
script/module/absAct/NewHeroLogic.lua

@@ -98,6 +98,7 @@ function getAndSendMsg(human, id, actId)
                 zhekou = 0,
                 voucher = 0,
                 productId = "",
+                nCanBuyNum = 0,
             }
         else
             BuyLogic.fontBuyItem(human, msgRet.giftlist[index].buyMsg[1], buyID)
@@ -116,7 +117,7 @@ function getgiftbybuyid(buyid)
     end
 end
 
-function newheroGift(human, id, buyConf, isFirst, cnt)
+function newheroGift(human, id, buyConf, isFirst, cnt, buyNum)
     local state = AbsActLogic.isStarted(human, id)
     local absConfig = AbsActExcel.absActivity[id]
     if absConfig == nil or not state then return end
@@ -139,6 +140,11 @@ function newheroGift(human, id, buyConf, isFirst, cnt)
         return
     end
 
+    -- if nowBuyCnt + buyNum >= config.limit then
+    --     Broadcast.sendErr(human, Lang.HERO_BAG_BUY_CAP_NO_CNT)
+    --     return
+    -- end
+
     -- 当金币购买之后超过最大金币时,不允许购买
     for j = 1, #config.reward do
         local itemID = config.reward[j][1]
@@ -151,6 +157,14 @@ function newheroGift(human, id, buyConf, isFirst, cnt)
     end
 
     -- 增加已购买次数
+    -- human.db.absAct[id].newheroCnt[giftid] = nowBuyCnt + buyNum
+    -- -- 发放物品
+    -- local items = { }
+    -- for _, v in ipairs(config.reward) do
+    --     table.insert(items, {v[1], v[2] * buyNum})
+    -- end
+    
+    -- BagLogic.addItemList(human, config.reward, "newhero_reward")
     human.db.absAct[id].newheroCnt[giftid] = nowBuyCnt + 1
     -- 发放物品
     -- local items = { }
@@ -222,4 +236,24 @@ function updateDaily(human, id)
         human.db.drawCard.list[8] = {}
     end
     AbsActLogic.actDetailQuery(human, ABS_ACT_ID)
- end
+ end
+
+-- function GetRemainNum(human, nBuyID)
+--     local config = AbsActExcel.absEva[nBuyID]
+--     if not config then
+--         return 0
+--     end
+
+--     local giftid = getgiftbybuyid(nBuyID)
+--     if not giftid then return 0 end
+
+--     if not human.db.absAct[ABS_ACT_ID].newheroCnt then
+--         return config.limit
+--     end
+
+--     if not human.db.absAct[ABS_ACT_ID].newheroCnt[giftid] then
+--         return config.limit
+--     else 
+--         return config.limit - human.db.absAct[ABS_ACT_ID].newheroCnt[giftid]
+--     end
+-- end

+ 47 - 17
script/module/absAct/PremiumGiftLogic.lua

@@ -13,7 +13,9 @@ local Log = require("common.Log")
 local YunYingLogic = require("yunying.YunYingLogic")
 local CycleActivityLogic = require("yunying.CycleActivity")
 
---
+-- 活动ID
+ABC_PREMIUM_GIFT_ACT_ID = 743
+
 ABS_PREMIUM_GIFT_LIST_ACTID = { }
 ABS_PREMIUM_GIFT_LIST_BUYID = { }
 function initAfterHot()
@@ -34,19 +36,17 @@ end
 
 --
 function isOpen(human, YYInfo, funcConfig)
-    -- return AbsActLogic.isStarted(human, funcConfig.funcID)
-    return CycleActivityLogic.isStarted(human, funcConfig.funcID)
+    return AbsActLogic.isStarted(human, funcConfig.funcID)
 end
 
 --
 function isRed(human, YYInfo, funcConfig)
-    -- local ret, endTime, startTime = AbsActLogic.isStarted(human, funcConfig.funcID)
-    local ret, endTime, startTime = CycleActivityLogic.isStarted(human, funcConfig.funcID)
+    local ret, endTime, startTime = AbsActLogic.isStarted(human, funcConfig.funcID)
     if ret == true then
         local id = funcConfig.funcID
         local absActConfig = AbsActExcel.absActivity[id]
         if not absActConfig then return end
-        -- AbsActLogic.checkAbsActClean(human, id)
+        AbsActLogic.checkAbsActClean(human, id)
         local absAct = human.db.absAct[id]
         if not absAct then
             return false
@@ -66,8 +66,7 @@ end
 
 --
 function getLeftTime(human, YInfo, funcConfig)
-    -- local ret, endTime, startTime = AbsActLogic.isStarted(human, funcConfig.funcID)
-    local ret, endTime, startTime = CycleActivityLogic.isStarted(human, funcConfig.funcID)
+    local ret, endTime, startTime = AbsActLogic.isStarted(human, funcConfig.funcID)
     if ret == true then
         return endTime - os.time()
     else
@@ -76,9 +75,8 @@ function getLeftTime(human, YInfo, funcConfig)
 end
 
 
-function premiumGift(human, id, buyConf, isFirst, cnt)
-    -- local state = AbsActLogic.isStarted(human, id)
-    local state = CycleActivityLogic.isStarted(human, id)
+function premiumGift(human, id, buyConf, isFirst, cnt, buyNum)
+    local state = AbsActLogic.isStarted(human, id)
     local absConfig = AbsActExcel.absActivity[id]
     if absConfig == nil or not state then return end
 
@@ -102,6 +100,11 @@ function premiumGift(human, id, buyConf, isFirst, cnt)
         return
     end
 
+    -- if nowBuyCnt + buyNum > config.cnt then
+    --     Broadcast.sendErr(human, Lang.HERO_BAG_BUY_CAP_NO_CNT)
+    --     return
+    -- end
+
     -- 当金币购买之后超过最大金币时,不允许购买
     for j = 1, #config.reward do
         local itemID = config.reward[j][1]
@@ -113,6 +116,15 @@ function premiumGift(human, id, buyConf, isFirst, cnt)
         end
     end
 
+    -- -- 增加已购买次数
+    -- human.db.absAct[id].premiumCnt[premiumID] = nowBuyCnt + buyNum
+    -- -- 发放物品
+    -- local items = { }
+    -- for _, v in ipairs(AbsActExcel.premiumGift[premiumID].reward) do
+    --     table.insert(items, {v[1], v[2]*buyNum})
+    -- end
+    -- BagLogic.addItemList(human, items, "premium_reward")
+
     -- 增加已购买次数
     human.db.absAct[id].premiumCnt[premiumID] = nowBuyCnt + 1
     -- 发放物品
@@ -125,8 +137,7 @@ end
 
 function getAndSendMsg(human, id, actId)
     local now = os.time()
-    -- local startedFlag, endTime, startTime = AbsActLogic.isStarted(human, id)
-    local startedFlag, endTime, startTime = CycleActivityLogic.isStarted(human, id)
+    local startedFlag, endTime, startTime = AbsActLogic.isStarted(human, id)
     if not startedFlag then return end
     local absActConfig = AbsActExcel.absActivity[id]
     if not absActConfig then return end
@@ -180,14 +191,13 @@ end
 
 
 function giftBuy(human, id, premiumID)
-    -- local state = AbsActLogic.isStarted(human, id)
-    local state = CycleActivityLogic.isStarted(human, id)
+    local state = AbsActLogic.isStarted(human, id)
     
     if state ~= true then return Broadcast.sendErr(human, Lang.ACT_WAS_OVER) end
     local absConfig = AbsActExcel.absActivity[id]
     if not absConfig then return end
 
-    -- AbsActLogic.checkAbsActClean(human, id)
+    AbsActLogic.checkAbsActClean(human, id)
 
     -- 存在多个特惠礼包 同时   开放
     local config = AbsActExcel.premiumGift[premiumID]
@@ -236,4 +246,24 @@ function giftBuy(human, id, premiumID)
 
     Broadcast.sendErr(human, Lang.ITEM_BUY_SUCCESS)
     AbsActLogic.actDetailQuery(human, id)
-end
+end
+
+-- function GetRemainNum(human, nBuyID)
+--     local premiumID = ABS_PREMIUM_GIFT_LIST_BUYID[nBuyID]
+--     if not premiumID then
+--         return 0
+--     end
+
+--     local config = AbsActExcel.premiumGift[premiumID]
+--     if not config then return 0 end
+
+--     if not human.db.absAct[ABC_PREMIUM_GIFT_ACT_ID].premiumCnt then
+--         return 0
+--     end
+
+--     if not human.db.absAct[ABC_PREMIUM_GIFT_ACT_ID].premiumCnt[premiumID] then
+--         return config.cnt
+--     else
+--         return config.cnt - human.db.absAct[ABC_PREMIUM_GIFT_ACT_ID].premiumCnt[premiumID]
+--     end
+-- end

+ 199 - 2
script/module/absAct/Proto.lua

@@ -2,7 +2,8 @@ local ItemData = require("bag.Proto").ItemData
 local BuyItem = require("topup.Proto").BuyItem
 local HeroSimple = require("hero.Proto").HeroSimple
 --local RechargeBackNet = require("present.Proto").RechargeBackNet
-local RoleBase = require("role.Proto").RoleBase 
+local RoleBase = require("role.Proto").RoleBase
+local GOODS = require("shop.Proto").GOODS
 
 -- 超值礼包
 PremiumGift = {
@@ -1416,6 +1417,7 @@ GC_CYCLMAKEFOOD_QUERY = {
     {"foodList",          9,            "string"},  -- 材料列表
     {"tagetFoodName",     1,            "string"},
     {"itemInfo",          1,            ItemData},  -- 消耗道具
+    {"isTenTimes",        1,            "byte"},    -- 是否选择10倍消耗, 0-没有, 1-选定了
 }
 
 -- 烹饪(合成食物)
@@ -1439,4 +1441,199 @@ GC_CYCLMAKEFOOD_GET_5STARfOODLIST = {
     {"isEnd",                       1,      "byte"},            -- 分段标识,0-没有发完,1-发完
 }
 
--------------------------------------------------------------------------------------
+-- 选择/取消  10倍消耗
+CG_CYCLMAKEFOOD_SELECT_MUL = {
+    {"actId",                       1,      "int"},     -- 活动ID
+    {"opType",                      1,      "byte"},     -- 操作类型, 0-取消10倍消耗, 1-选择10倍消耗
+}
+
+-------------------------------------------------------------------------------------
+
+---------------------新商业活动3-七日挑战-------------------
+TaskInfo = {
+    {"nID",             1,      "int"},         -- 任务编号
+    {"nState",          1,      "byte"},        -- 0 不可领取 1 - 可领取 2- 已领取
+    {"nDay",            1,      "byte"},        -- 天数
+    {"nValue",          1,      "int"},         -- 任务需要完成次数
+    -- {"nPoint",          1,      "byte"},        -- 完成获得积分
+    {"Desc",            1,      "string"},      -- 任务描述
+    {"nFinish",         1,      "int"},         -- 当前完成次数
+    {"item",            5,      ItemData},      -- 奖励信息
+}
+
+TaskPointInfo = {
+    {"nID",             1,      "int"},         -- 积分奖励ID
+    {"nNeedPoint",      1,      "int"},         -- 需要积分
+    {"nState",          1,      "byte"},        -- 0 不可领取 1 - 可领取 2- 已领取
+    {"item",            5,      ItemData},      -- 奖励信息
+}
+
+-- 请求结任务信息
+CG_NEW_BUSTHREEACT_TASKQUERY = {
+    {"nDay",            1,      "int"},     
+}
+
+-- 任务信息回复协议
+GC_NEW_BUSTHREEACT_TASKQUERY = 
+{
+    {"nDay",        1,    "int"},           -- 天数
+    {"nNowPoint",   1,    "int"},           -- 当前积分
+    {"nNowDay",     1,    "int"},           -- 当前是第几天
+    {"list",        15,   TaskInfo},        -- 奖励信息
+    {"tRed",        8,     "byte"},         -- 天数红点 0 没有 1有
+}
+
+-- 请求领取任务奖励 
+CG_NEW_BUSTHREEACT_GETTASKPRIZE = 
+{
+   {"nDay",         1,     "int"},          -- 天数
+}
+
+-- 请求任务积分信息
+CG_NEW_BUSTHREEACT_TASKPOINTQUERY = {
+}
+
+-- 请求任务积分信息回包
+GC_NEW_BUSTHREEACT_TASKPOINTQUERY = 
+{
+    {"nNowPoint",   1,      "int"},         -- 当前积分
+    {"listPoint",   8,    TaskPointInfo}    -- 积分信息
+}
+
+-- 领取任务积分奖励
+CG_NEW_BUSTHREEACT_GETTASKPOINTPRIZE = {}
+
+---------------------新商业活动3-天选兑换-------------------
+-- 查询商品数据
+CG_NEW_BUSTHREEACT_DISQUERY = {}
+
+--查询返回协议
+GC_NEW_BUSTHREEACT_DISQUERY = {
+    {"titemData",                         20,       ITEM_INFO},         --所有商品数据
+}
+
+--购买请求协议
+CG_NEW_BUSTHREEACT_DISBUY = {
+    {"id",			                    1,      "int"},               -- 活动ID
+    {"idx",                             1,       "byte"},             -- 商品索引
+    {"buyCnt",                          1,       "int"},              --购买的份数
+}
+
+---------------------新商业活动3-天选豪礼-------------------
+-- 请求天选豪礼
+CG_NEW_BUSTHREEACT_GRANDGIFT_QUERY = {}
+
+
+-- 回复天选豪礼
+GC_NEW_BUSTHREEACT_GRANDGIFT_QUERY = {
+    {"tList",       20,     BUSONEACTYUANZHENG}
+}
+
+-- 请求领取天选豪礼
+CG_NEW_BUSTHREEACT_GRANDGIFT_GET = {}
+
+---------------------新商业活动3-天选骰子-------------------
+DICEPRIZE = {
+    {"tPoint",      1,      "string"},    -- 1|2|3
+    {"titemData",   5,      ItemData},  -- 对应的奖励配置
+}
+-- 抽取
+CG_NEW_BUSTHREEACT_DICEDO = {
+    {"nNum",        1,      "byte"},    -- 次数
+}
+
+-- 奖励回复
+GC_NEW_BUSTHREEACT_DICEDO = {
+    {"tPrize",      10,     DICEPRIZE},     -- 奖励配置
+}
+
+---------------------节日活动 - 个人BOSS -------------------
+BOSSPRIZEINFO = {
+    {"nID",         1,      "int"},         -- 奖励ID
+    {"nHarm",       1,      "double"},      -- 伤害值
+    {"nState",      1,      "byte"},        -- 0 不可领取 1 - 可领取 2- 已领取
+    {"tPrize",      5,      ItemData},      -- 奖励信息
+}
+
+-- 请求个人BOSS主界面数据
+CG_ABS_FESTIVAL_BOSS_QUERY = {}
+
+-- 回复个人BOSS主界面数据
+GC_ABS_FESTIVAL_BOSS_QUERY = {
+    {"nNum",        1,      "byte"},        -- 挑战次数
+    {"nMaxNum",     1,      "byte"},        -- 最大挑战次数
+    {"bRedPrize",   1,      "byte"},        -- 是否有奖励红点
+    {"nHarm",       1,      "double"},      -- 当前伤害
+}
+
+-- 请求奖励信息
+CG_ABS_FESTIVAL_BOSS_REWARD = {}
+
+-- 回复奖励信息
+GC_ABS_FESTIVAL_BOSS_REWARD = {
+    {"tPrize",      25,     BOSSPRIZEINFO},      -- 奖励信息
+}
+
+-- 领取奖励
+CG_ABS_FESTIVAL_BOSS_GET = {}
+
+---------------------节日活动 - 商店 -------------------
+-- 请求商店数据
+CG_ABS_FESTIVAL_SHOP_QUERY = {}
+
+-- 回复商店数据
+GC_ABS_FESTIVAL_SHOP_QUERY = {
+    {"tGoodInfo",   15,      GOODS},         -- 物品信息
+}
+
+-- 购买物品
+CG_ABS_FESTIVAL_SHOP_BUY = {
+    {"nID",         1,      "int"},         -- 物品ID
+    {"nCnt",        1,      "int"},         -- 购买数量
+}
+
+---------------------节日活动 - 限时累充 -------------------
+FESTIVALRECHARGEINFO = {
+    {"nID",         1,      "int"},         -- 奖励ID
+    {"nState",      1,      "byte"},        -- 0 不可领取 1 - 可领取 2- 已领取
+    {"nNeedCharge", 1,      "int"},         -- 需要充值金额
+    {"tPrize",      5,      ItemData},      -- 奖励信息
+}
+
+-- 请求累充数据
+CG_ABS_FESTIVAL_RECHARGE_QUERY = {}
+
+-- 回复累充数据
+GC_ABS_FESTIVAL_RECHARGE_QUERY = {
+    {"nNowCharge",  1,      "int"},         -- 当前充值金额
+    {"tPrize",      25,     FESTIVALRECHARGEINFO},      -- 奖励信息
+}
+
+-- 领取奖励
+CG_ABS_FESTIVAL_RECHARGE_GET = {
+    {"nID",         1,      "int"},         -- 奖励ID
+}
+
+---------------------节日活动 - 限时寻宝 -------------------
+FESTIVALSEVENDAYCARD = {
+    {"nID",         1,      "int"},         -- 奖励ID
+    {"nRare",       1,      "byte"},        -- 稀有度 0-普通 1-稀有 2-史诗
+    {"tPrize",      1,      ItemData},      -- 奖励信息
+}
+
+-- 请求限时寻宝数据
+CG_ABS_FESTIVAL_SEVENDAY_CARD_QUERY = {}
+
+-- 回复限时寻宝数据
+GC_ABS_FESTIVAL_SEVENDAY_CARD_QUERY = {
+    {"nFreeNum",   1,      "int"},        -- 当前免费次数
+    {"nNowNum",   1,      "int"},         -- 当前抽取次数
+    {"nMaxNum",   1,      "int"},         -- 保底次数
+    {"tUseItem", 1,      ItemData},      -- 抽取消耗道具
+    {"tPrize",    25,     FESTIVALSEVENDAYCARD},      -- 奖励信息
+}
+
+-- 抽取
+CG_ABS_FESTIVAL_SEVENDAY_CARD_DO = {
+    {"nType",       1,      "byte"},        -- 抽取类型 1-单抽 2-十连
+}

+ 10 - 10
script/module/absAct/SingleReachLogic.lua

@@ -18,8 +18,8 @@ local Msg = require("core.Msg")
 local Grid = require("bag.Grid")
 local BagLogic = require("bag.BagLogic")
 local BuyLogic = require("topup.BuyLogic")
-local ObjHuman = require("core.ObjHuman")
-local Lang  = require("common.Lang")
+local ObjHuman = require("core.ObjHuman")
+local Lang  = require("common.Lang")
 local Broadcast = require("broadcast.Broadcast")
 local YunYingLogic = require("yunying.YunYingLogic")
 
@@ -58,7 +58,7 @@ local function fontDabiaoNet(db,net,config,id)
 end
 
 function getAndSendMsg(human,id)
-    -- 判断活动是否开起
+    -- 鍒ゆ柇娲诲姩鏄�惁寮€璧�
     local state, endTime, starTime = AbsActLogic.isStarted(human, id)
     if not state then return end
 
@@ -96,14 +96,14 @@ function touchSingleReach(human,id,param)
         return
     end
 
-    --增加钻石使用数量 
+    --澧炲姞閽荤煶浣跨敤鏁伴噺 
     absAct.reward = absAct.reward or {}
 
     local config = AbsActExcel.singleReach
     local len = #config
     for i = 1,len do
         if config[i].actId == absConfig.actId and config[i].mainId == id then
-            -- 判断钻石使用数量是否达标了
+             -- 鍒ゆ柇閽荤煶浣跨敤鏁伴噺鏄�惁杈炬爣浜�
             absAct.reward[i] = absAct.reward[i] or {}
             absAct.reward[i].state = absAct.reward[i].state or 0
             absAct.reward[i].cnt = absAct.reward[i].cnt or 0
@@ -121,7 +121,7 @@ end
 
 
 function getSingleReachReward(human,id,giftId)
-     -- 判断活动是否开启
+     -- 鍒ゆ柇娲诲姩鏄�惁寮€鍚�
     local state, endTime, starTime = AbsActLogic.isStarted(human, id)
     if not state then return end
 
@@ -133,7 +133,7 @@ function getSingleReachReward(human,id,giftId)
         return
     end
 
-    -- 状态不为可领,返回
+    -- 鐘舵€佷笉涓哄彲棰嗭紝杩斿洖
     absAct.reward = absAct.reward or {}
     if not absAct.reward[giftId] or absAct.reward[giftId].state ~= 1 or absAct.reward[giftId].getCnt <= 0 then
         return
@@ -145,7 +145,7 @@ function getSingleReachReward(human,id,giftId)
         return
     end
 
-    -- 设置状态为已领取
+    -- 璁剧疆鐘舵€佷负宸查�鍙�
     absAct.reward[giftId].state = 2
     absAct.reward[giftId].cnt = absAct.reward[giftId].cnt + 1
     absAct.reward[giftId].getCnt = absAct.reward[giftId].getCnt - 1
@@ -155,7 +155,7 @@ function getSingleReachReward(human,id,giftId)
     elseif absAct.reward[giftId].cnt < config.maxCnt then
         absAct.reward[giftId].state = 0
     end
-    -- 发奖励
+    -- 鍙戝�鍔�
     BagLogic.addItemList(human, config.item, "abs_singleReach")   
     getAndSendMsg(human,id)
     
@@ -183,7 +183,7 @@ function isRed(human, YYInfo, funcConfig)
 end
 
 function updateDaily(human,id)
-    -- 判断活动是否开启
+    -- 鍒ゆ柇娲诲姩鏄�惁寮€鍚�
     local state, endTime, starTime = AbsActLogic.isStarted(human, id)
     if not state then return end
 

+ 41 - 5
script/module/absAct/SpecialCustomLogic.lua

@@ -222,11 +222,11 @@ function selectItem(human,id,giftId,first,second,third)
 end
 
 -- 购买礼包
-function custom(human,funcID,conf)
-    customBuy(human,conf.args[1],funcID, true)
+function custom(human,funcID, conf, isFirst, cnt, buyNum)
+    customBuy(human,conf.args[1],funcID, true, buyNum)
 end
 
-function customBuy(human,args,id, bFromPay)
+function customBuy(human,args,id, bFromPay, buyNum)
      -- 活动未开,返回
     local state, endTime, starTime = AbsActLogic.isStarted(human, id)
     if not state then return end
@@ -238,6 +238,8 @@ function customBuy(human,args,id, bFromPay)
         return
     end
 
+    -- buyNum = buyNum or 1
+
     -- 检查来源
     local tConfig = AbsActExcel.custom[args]
     if not tConfig then
@@ -270,6 +272,10 @@ function customBuy(human,args,id, bFromPay)
         return
     end
 
+    -- if buyNum + absAct.custom[args].cnt > config.limitCnt then
+    --     return
+    -- end
+
     -- 钻石价格不为0时,表示钻石购买,则需判断钻石是否足够
     if config.price ~= 0 then
 	    if not ObjHuman.checkRMB(human, config.price) then
@@ -278,8 +284,9 @@ function customBuy(human,args,id, bFromPay)
 	    ObjHuman.decZuanshi(human, -config.price, "abs_custom")
     end
 
-     -- 购买次数增加一次
+    -- 购买次数增加一次
     absAct.custom[args].cnt = absAct.custom[args].cnt + 1
+    -- absAct.custom[args].cnt = absAct.custom[args].cnt + buyNum
 
      -- 状态设置为已卖完,此时,为防止后续报错,导致可无限购买,故先设置为无法继续购买
     absAct.custom[args].state = 2
@@ -288,9 +295,11 @@ function customBuy(human,args,id, bFromPay)
     local item = {}
     for i = 1, #config.fixed do
         item[#item+1] = {config.fixed[i][1],config.fixed[i][2]}
+        -- item[#item+1] = {config.fixed[i][1],config.fixed[i][2] * buyNum}
     end
     for i = 1,#absAct.custom[args].selectItem do
         item[#item+1] = {absAct.custom[args].selectItem[i][1],absAct.custom[args].selectItem[i][2]}
+        -- item[#item+1] = {absAct.custom[args].selectItem[i][1],absAct.custom[args].selectItem[i][2]*buyNum}
     end
     BagLogic.addItemList(human, item, "abs_custom")   
 
@@ -337,4 +346,31 @@ function isRed(human, YYInfo, funcConfig)
     end
 
     return bRed
-end
+end
+
+-- function GetRemainNum(human, nBuyID)
+--     local tConfig = AbsActExcel.custom
+--     local nChoseID, nLimitNum = nil, nil
+--     for nID, v in pairs(tConfig) do
+--         if v.buyID == nBuyID and nID < SPECIALCISTOMNOBUYID then
+--             nChoseID = nID
+--             nLimitNum = v.limitCnt
+--             break
+--         end
+--     end
+
+--     local tActDBData = human.db.absAct[SPECIALCISTOMACTID]
+--     if not tActDBData then
+--         return 0
+--     end
+
+--     if not nChoseID then
+--         return 0
+--     end
+
+--     if tActDBData.custom and tActDBData.custom[nChoseID] and tActDBData.custom[nChoseID].cnt then
+--         return tActDBData.custom[nChoseID].cnt >= nLimitNum and 0 or (nLimitNum - tActDBData.custom[nChoseID].cnt)
+--     else
+--         return nLimitNum
+--     end
+-- end

+ 925 - 0
script/module/areaBattle/AreaBattleCS.lua

@@ -0,0 +1,925 @@
+-- 战区争霸(跨服)
+local InnerMsg = require("core.InnerMsg")
+local Log = require("common.Log")
+local Timer = require("core.Timer")
+local Util = require("common.Util")
+local MiddleManager = require("middle.MiddleManager")
+local AreaBattleDB = require("areaBattle.AreaBattleDB")
+local AreaBattleDefine = require("areaBattle.AreaBattleDefine")
+local CombatVideo = require("combat.CombatVideo")
+local CombatDefine = require("combat.CombatDefine")
+local CombatLogicCS = require("combat.CombatLogicCS")
+local BattleDataCS = require("battleDataManager.BattleDataCS")
+
+-- 当天处于星期几(星期六为7, 星期天为1)
+local wDay
+
+-- 玩家战斗数据缓存表
+local battleDataCache = {}
+
+-- 请求序列表, 用于向普通获取玩家战斗数据
+local requestArr = {}
+
+
+local function updateWDay()
+    wDay = Util.getWeekDay()
+end
+
+local function getTodayStartTime()
+    local now = os.time()
+    return Util.getDayStartTime(now)
+end
+
+local function isOpen()
+    if not wDay then
+        updateWDay()
+    end
+
+    if not table.find(AreaBattleDefine.OPEN_WDAY_AREA, wDay) then
+        return false
+    end
+
+    local now = os.time()
+    local toDayStartTime = getTodayStartTime()
+
+    if wDay == AreaBattleDefine.OPEN_WDAY_AREA[1] and now < (toDayStartTime + AreaBattleDefine.PREPARE_STATE_START_SEC) then
+        return false
+    end
+
+    if wDay == AreaBattleDefine.OPEN_WDAY_AREA[2] and now > (toDayStartTime + AreaBattleDefine.END_STATE_START_SEC) then
+        return false
+    end
+
+    return true
+end
+
+-- 参战服务器日志格式: "serverId1, serverId2,serverId3"
+-- 服务器匹配列表日志格式: "serverId1-serverId2-serverId3-serverId4", 从一个serverId开始, 按顺序每两个serverId匹配到一起战斗
+-- 参战服务器信息日志个数: serverId | 本服战胜次数| 本服战败次数 | 战胜玩家uuid-战胜玩家uui
+local function writeLog(logStr)
+    Log.write(Log.LOGID_OSS_AREABATTLE_BATTLE, logStr)
+end
+
+
+-- 计算一个服的总战力
+local function calcSrvPower(playerArray)
+    local power = 0
+    for _, v in ipairs(playerArray or {}) do
+        power = power + (v.power or 0)
+    end
+    return power
+end
+
+-- 获取战斗对象的区服Id, uuid 
+local function getBattleObjInfo(matchIdx, battleIdx, objIdentity)
+    local matchSrvArr = AreaBattleDB.GetMatchSrvArr()
+
+    local matchData = matchSrvArr[matchIdx]
+    if not matchData then
+        return
+    end
+
+    local targetSrvId = matchData[objIdentity]
+    if not targetSrvId then
+        return
+    end
+
+    local serverList = AreaBattleDB.GetServerList()
+    if not serverList[targetSrvId] then
+        return
+    end
+
+    local srvPlayerArr = serverList[targetSrvId].playerInfoArr
+    local playerInfo = srvPlayerArr[battleIdx]
+
+    return targetSrvId, playerInfo and playerInfo.uuid
+end
+
+
+-- 进入新一轮的处理
+local function newRoundHandle()
+    local stateDB = AreaBattleDB.GetState()
+
+    -- 上一轮奖励没有发放, 在新一轮开始时, 先发奖
+    if stateDB == AreaBattleDefine.STATE_AWARD then
+        AwardPrizesHandle()
+    end
+
+    -- 清除录像数据
+    CombatVideo.ClearOutVideoByCombatType(CombatVideo.VIDEOTYPE_AREABATTLE)
+
+    -- 重置录像缓存
+    AreaBattleDB.ResetVideoShowCache()
+
+    -- 重置战区争霸数据
+    AreaBattleDB.ResetData()
+
+    -- 更新状态
+    AreaBattleDB.UpdateState(AreaBattleDefine.STATE_PREPARE)
+
+    -- 通知普通服
+    NotifySrvJoin()
+
+
+    -- 重置缓存数据
+    battleDataCache = {}
+    requestArr = {}
+end
+
+-- 服务器分组算法
+local function matchAlgorithm(serverArr, len)
+    local usedTb = {}
+    local pairTb = {}
+
+    local function getNextUnuseIdx(nowIdx)
+        for i=nowIdx, len do
+            if not usedTb[i] then
+                return i
+            end
+        end
+    end
+
+    local function checkRandIdx(startIdx, endIdx)
+        local tbl= {}
+        for i= startIdx, endIdx do
+            if i <= len and not usedTb[i] then
+                table.insert(tbl, i)
+            end
+        end
+        return tbl
+    end
+
+    local currentIdx = 1
+    while currentIdx <= len do
+        currentIdx = getNextUnuseIdx(currentIdx)
+        if not currentIdx then
+            break
+        end
+
+        local startIdx = currentIdx+1
+        local endIdx = currentIdx+3
+        local correctTb = checkRandIdx(startIdx, endIdx)
+        local matchIdx = correctTb[math.random(1, #correctTb)]
+
+        usedTb[currentIdx] = true
+        usedTb[matchIdx] = true
+        table.insert(pairTb, {serverArr[currentIdx], serverArr[matchIdx]})
+        currentIdx = currentIdx + 1
+    end
+
+    return pairTb
+end
+
+-- 生成匹配列表
+local function genMacthArr()
+    local joinSrvArr = AreaBattleDB.GetJoinSrvArr()
+    local joinSrvArr_cp = Util.copyTable(joinSrvArr)
+    if not joinSrvArr_cp or #joinSrvArr_cp <= 0 then
+        return
+    end
+
+    local srvCnt = #joinSrvArr_cp
+    if srvCnt > 1 then
+        if srvCnt % 2 ~= 0 then
+            local deleteSrvId = joinSrvArr_cp[srvCnt]
+            joinSrvArr_cp[srvCnt] = nil
+            srvCnt = srvCnt - 1
+
+            -- 把被移除的服务器从服务器数据列表中移除
+            local serverList = AreaBattleDB.GetServerList()
+            serverList[deleteSrvId] = nil
+            AreaBattleDB.UpdateServerList(serverList)
+
+            -- 记录日志
+            local logStr = "移除多余的区服, 区服Id:  " .. deleteSrvId
+            writeLog(logStr)
+        end
+
+        table.sort(joinSrvArr_cp)
+        local matchArr = matchAlgorithm(joinSrvArr_cp, srvCnt)
+        AreaBattleDB.UpdateMatchSrvArr(matchArr)
+    end
+end
+
+-- 获取玩家的战斗数据
+local function getPlayerBattleData(serverId, playerUuid, extraArgs)
+    extraArgs.serverId = serverId
+    extraArgs.playerUuid = playerUuid
+    BattleDataCS.GetPlayerCombatData(serverId, playerUuid, BattleDataCS.AREABTTLE_TAG, CombatDefine.COMBAT_TYPE33, extraArgs)
+end
+
+-- 分批请求玩家战斗数据
+function Timed_GetPlayerBattleData()
+    if not requestArr or not next(requestArr) then
+        return
+    end
+
+    local maxNum = math.min(#requestArr, AreaBattleDefine.GET_BATTLE_MAX_CNT_TIMES)
+    for i=1, maxNum do
+        local info = table.remove(requestArr)
+        getPlayerBattleData(info[1], info[2], info[3])
+    end
+
+    if #requestArr > 0 then
+        Timer.addLater(2, Timed_GetPlayerBattleData, requestArr)
+    end
+end
+
+-- 向普通服请求战斗数据
+local function requestPlayerBattleData()
+    local matchSrvArr = AreaBattleDB.GetMatchSrvArr()
+    local serverList = AreaBattleDB.GetServerList()
+    if not matchSrvArr or #matchSrvArr == 0 or not next(serverList) then
+        return
+    end
+
+    for idx, matchSrvTb in ipairs(matchSrvArr) do
+        local serverId1 = matchSrvTb[1]
+        local serverId2 = matchSrvTb[2]
+        local playerArr1 = serverList[serverId1] and serverList[serverId1].playerInfoArr or {}
+        local playerArr2 = serverList[serverId2] and serverList[serverId2].playerInfoArr or {}
+        local maxPlayerCnt = math.max(#playerArr1, #playerArr2)
+
+        for i=1, maxPlayerCnt do
+            local playerUuid1 = playerArr1[i] and playerArr1[i].uuid
+            local playerUuid2 = playerArr2[i] and playerArr2[i].uuid
+
+            if playerUuid1 then
+                local args = {
+                    firstIdx = idx,
+                    secondIdx = i,
+                    identity = 1, --身份,1-进攻方, 2-防御方
+                    serverId = 0,
+                    playerUuid = "",
+                }
+                -- getPlayerBattleData(serverId1, playerUuid1, args)
+                requestArr[#requestArr+1] = {serverId1, playerUuid1, args}
+            end
+
+            if playerUuid2 then
+                local args = {
+                    firstIdx = idx,
+                    secondIdx = i,
+                    identity = 2, --身份,1-进攻方, 2-防御方
+                    serverId = 0,
+                    playerUuid = "",
+                }
+                -- getPlayerBattleData(serverId2, playerUuid2, args)
+                requestArr[#requestArr+1] = {serverId2, playerUuid2, args}
+            end
+        end
+    end
+
+    local now = os.time()
+    AreaBattleDB.UpdateUpLoadStartTi(now)
+
+    Timed_GetPlayerBattleData()
+end
+
+
+
+-- 处于准备阶段处理, 给服务器进行匹配, 并通知普通服上传玩家战斗数据
+local function prepareHandle()
+    local stateDB = AreaBattleDB.GetState()
+    if stateDB ~= AreaBattleDefine.STATE_PREPARE then
+        return
+    end
+
+    -- 服务器进行匹配
+    genMacthArr()
+
+    -- 让普通服上传战斗数据
+    -- requestPlayerBattleData()
+end
+
+-- 上一轮 ~ 新一轮准备阶段的处理
+local function earlyHanle()
+    local now = os.time()
+    local stateDB = AreaBattleDB.GetState()
+    local nowRoundStartTi = AreaBattleDB.GetNowRoundStartTi()
+    local diffDays = Util.diffDay(nowRoundStartTi)
+
+    -- 开启新一轮活动
+    if nowRoundStartTi <= 0 or diffDays >= 2 then
+        return newRoundHandle()
+    end
+
+    -- 处于准备阶段, 普通服上传完本服排名前15的玩家数据后,如果还没有对服务器进行分组, 则生成服务器匹配列表, 并通知这些服务器上传本服玩家战斗数据
+    if diffDays < 2 and now - nowRoundStartTi >= AreaBattleDefine.SERVER_DATA_TIME and stateDB == AreaBattleDefine.STATE_PREPARE then
+        local matchSrvArr = AreaBattleDB.GetMatchSrvArr()
+        if not matchSrvArr or not next(matchSrvArr) then
+            prepareHandle()
+        end
+    end
+end
+
+
+-- 进入战斗阶段的处理
+local function BattleStageHandle()
+    local stateDB = AreaBattleDB.GetState()
+    if stateDB ~= AreaBattleDefine.STATE_BATTLE then
+        return
+    end
+
+    StartBattle()
+end
+
+-- 战斗结束,  把结果更新到DB
+local function updateDBBattleResult(battleInfo)
+    local attackerServerId = battleInfo.attackerServerId
+    local attackerUuid = battleInfo.attackerUuid
+    local defenerServerId = battleInfo.defenerServerId
+    local defenerUuid = battleInfo.defenerUuid
+    local isWin = battleInfo.isWin
+    local serverList = AreaBattleDB.GetServerList()
+
+    local attackerSrvData = serverList[attackerServerId]
+    if attackerSrvData then
+        if isWin == 1 then
+            attackerSrvData.winTimes = (attackerSrvData.winTimes or 0) + 1
+            attackerSrvData.winPlayerArr = attackerSrvData.winPlayerArr or {}
+            table.insert(attackerSrvData.winPlayerArr, attackerUuid)
+        else
+            attackerSrvData.defeatTimes = (attackerSrvData.defeatTimes or 0) + 1
+        end
+    end
+
+    local defenerSrvData = serverList[defenerServerId]
+    if defenerSrvData then
+        if isWin == 0 then
+            defenerSrvData.winTimes = (defenerSrvData.winTimes or 0) + 1
+            defenerSrvData.winPlayerArr = defenerSrvData.winPlayerArr or {}
+            table.insert(defenerSrvData.winPlayerArr, defenerUuid)
+        else
+            defenerSrvData.defeatTimes = (defenerSrvData.defeatTimes or 0) + 1
+        end
+    end
+
+    AreaBattleDB.UpdateServerList(serverList)
+end
+
+
+-- 生成用于通知各个普通服发奖的数据
+local function genNotifyInfo(serverInfo)
+    local info = {
+        isWin = 0,
+        winPlayerArr = {},
+        defeatPlayerArr = {}
+    }
+
+    if (serverInfo.winTimes or 0) > (serverInfo.defeatTimes or 0) then
+        info.isWin = 1
+    end
+
+    for _, playerInfo in ipairs(serverInfo.playerInfoArr) do
+        if table.find(serverInfo.winPlayerArr, playerInfo.uuid) then
+            table.insert(info.winPlayerArr, playerInfo.uuid)
+        else
+            table.insert(info.defeatPlayerArr, playerInfo.uuid)
+        end
+    end
+
+    return info
+end
+
+-- 生成日志
+local function genLog()
+    local t1, t2 = {}, {}
+
+    local joinSrvArr = AreaBattleDB.GetJoinSrvArr()
+    for idx, srvId in ipairs(joinSrvArr or {}) do
+        t1[idx] = srvId
+    end
+    local str1 = table.concat(t1, ",")
+    writeLog(str1)
+
+
+    local len = 0
+    local matchSrvArr = AreaBattleDB.GetMatchSrvArr()
+    for _, srvTb in ipairs(matchSrvArr or {}) do
+        for _, servrId in ipairs(srvTb) do
+            len = len + 1
+            t2[len] = servrId
+        end
+    end
+
+    local str2 = table.concat(t2, "-")
+    writeLog(str2)
+
+
+
+    local serverList = AreaBattleDB.GetServerList()
+    for serverId, srvInfo in pairs(serverList or {}) do
+        local t = {serverId, srvInfo.winTimes or 0, srvInfo.defeatTimes or 0}
+        if srvInfo.winPlayerArr and #srvInfo.winPlayerArr > 0 then
+            local s = table.concat(Util.copyTable(srvInfo.winPlayerArr), "-")
+            table.insert(t, s)
+        end
+
+        local str3 = table.concat(t, "|")
+        writeLog(str3)
+    end
+end
+
+
+-------------------------------------------C2N-------------------------------------------
+
+-- 通知普通服,争霸开始
+function NotifySrvJoin()
+    local msgData = InnerMsg.wl.WL_AREABATTLE_OPEN
+    local fdList = MiddleManager.MiddleManager_GetAllFD()
+    for _, fd in pairs(fdList) do
+        InnerMsg.sendMsg(fd, msgData)
+    end
+end
+
+-- 通知普通服发奖
+function NotifySrvAwardPrizes(fd, args)
+    local msgData = InnerMsg.wl.WL_AREABATTLE_SEND_REWARD
+    msgData.srvBattleRes = args
+    InnerMsg.sendMsg(fd, msgData)
+end
+
+-------------------------------------------N2C-----------------------------------------------
+
+-- 普通服加入战斗
+function N2C_JoinBattle(msg)
+    local sourceServerId = msg.sourceServerId
+    local joinBattleArray = msg.joinBattleArray
+
+    local joinSrvArr = AreaBattleDB.GetJoinSrvArr()
+    local serverList = AreaBattleDB.GetServerList()
+
+    if not table.find(joinSrvArr, sourceServerId) and not serverList[sourceServerId] then
+        -- 参战列表
+        table.insert(joinSrvArr, sourceServerId)
+        AreaBattleDB.UpdateJoinSrvArr(joinSrvArr)
+
+        -- 服务器列表
+        serverList[sourceServerId] = {
+            winTimes = 0,
+            defeatTimes = 0,
+            winPlayerArr = {},
+            playerInfoArr = joinBattleArray
+        }
+        AreaBattleDB.UpdateServerList(serverList)
+    end
+end
+
+-- 普通服请求争霸活动的基本数据
+function N2C_GetBaseInfo(msg)
+    local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId)
+    local msgData = InnerMsg.wl.WL_AREABATTLE_BASEINFO_QUERY
+    msgData.playerUuid = msg.playerUuid
+
+    local state = AreaBattleDB.GetState()
+    msgData.stage = state
+    msgData.startTime, msgData.endTime = 0, 0
+    local toDayStartTime = getTodayStartTime()
+
+    if not wDay then
+        updateWDay()
+    end
+
+    if wDay == AreaBattleDefine.OPEN_WDAY_AREA[1] then
+        msgData.startTime = toDayStartTime + AreaBattleDefine.PREPARE_STATE_START_SEC
+        msgData.endTime = toDayStartTime + 86400 + AreaBattleDefine.END_STATE_START_SEC
+
+    elseif wDay == AreaBattleDefine.OPEN_WDAY_AREA[2] then
+        msgData.startTime = toDayStartTime - 86400 + AreaBattleDefine.PREPARE_STATE_START_SEC
+        msgData.endTime = toDayStartTime + AreaBattleDefine.END_STATE_START_SEC
+
+        local now = os.time()
+        if state == AreaBattleDefine.STATE_AWARD and now < toDayStartTime + AreaBattleDefine.END_STATE_START_SEC then
+            msgData.stage = AreaBattleDefine.STATE_BATTLE
+        end
+    else
+        local subDay = AreaBattleDefine.OPEN_WDAY_AREA[1] - wDay
+        msgData.startTime = toDayStartTime + subDay * 86400 + AreaBattleDefine.PREPARE_STATE_START_SEC
+        msgData.endTime = toDayStartTime + (subDay + 1) * 86400 + AreaBattleDefine.END_STATE_START_SEC
+    end
+
+    InnerMsg.sendMsg(fd, msgData)
+end
+
+-- 普通服请求本服参战玩家列表
+function N2C_GetJoinPlayerArr(msg)
+    local sourceServerId = msg.sourceServerId
+    local fd = MiddleManager.getFDBySvrIndex(sourceServerId)
+    local msgData = InnerMsg.wl.WL_AREABATTLE_JOINPLAYER_QUERY
+    msgData.errCode = 0
+    msgData.playerArray = {}
+    msgData.playerUuid = msg.playerUuid
+
+    local joinSrvArr = AreaBattleDB.GetJoinSrvArr()
+    local mathcList = AreaBattleDB.GetMatchSrvArr()
+
+    -- 没有参加
+    if not joinSrvArr or not table.find(joinSrvArr, sourceServerId) then
+        msgData.errCode = -1
+        return InnerMsg.sendMsg(fd, msgData)
+    end
+
+    -- 匹配列表还没生成
+    if not mathcList or not next(mathcList) then
+        msgData.errCode = -2
+        return InnerMsg.sendMsg(fd, msgData)
+    end
+
+
+    local isInMathcArr = false
+    for _, matchSrvTb in ipairs(mathcList) do
+        if table.find(matchSrvTb, sourceServerId) then
+            isInMathcArr = true
+            break
+        end
+    end
+    -- 参加了,但是被移除, 没有在本轮匹配列表中
+    if not isInMathcArr then
+        msgData.errCode = -3
+        return InnerMsg.sendMsg(fd, msgData)
+    end
+
+    local serverList = AreaBattleDB.GetServerList()
+    msgData.playerArray = serverList[sourceServerId] and serverList[sourceServerId].playerInfoArr or {}
+    InnerMsg.sendMsg(fd, msgData)
+end
+
+
+-- 普通服请求本次参战的区服的匹配列表
+-- {    { {server1, power1}, {server2, power2} },   }
+function N2C_GetMatchList(msg)
+    local sourceServerId = msg.sourceServerId
+    local fd = MiddleManager.getFDBySvrIndex(sourceServerId)
+    local msgData = InnerMsg.wl.WL_AREABATTLE_MATCHLIST_QUERY
+    msgData.playerUuid = msg.playerUuid
+    msgData.matchList = {}
+
+    local mathcList = AreaBattleDB.GetMatchSrvArr()
+    local serverList = AreaBattleDB.GetServerList()
+
+    for k, matchSrvTb in ipairs(mathcList) do
+        msgData.matchList[k] = {}
+
+        for idx, serverId in ipairs(matchSrvTb) do
+            if serverList[serverId] then
+                -- table.insert(msgData.matchList[k], serverId)
+                local power = calcSrvPower(serverList[serverId].playerInfoArr)
+                -- table.insert(msgData.matchList[k], power)
+                msgData.matchList[k][idx] = {serverId, power}
+            end
+        end
+
+    end
+
+    InnerMsg.sendMsg(fd, msgData)
+end
+
+-- 普通服请求本服的战斗录像展示数据
+function N2C_GetVideoShowData(msg)
+    local sourceServerId = msg.sourceServerId
+    local fd = MiddleManager.getFDBySvrIndex(sourceServerId)
+
+    local msgData = InnerMsg.wl.WL_AREABATTLE_VIDEOSHOW_QUERY
+    msgData.errCode = 0
+    msgData.playerUuid = msg.playerUuid
+    msgData.videoShowData = {}
+    msgData.srvInfo = {}
+
+    local state = AreaBattleDB.GetState()
+    if state ~= AreaBattleDefine.STATE_AWARD and state ~= AreaBattleDefine.STATE_END then
+        msgData.errCode = -1
+        return InnerMsg.sendMsg(fd, msgData)
+    end
+
+    local videoSecondIdx, leftSrvId, rightSrvId = 0, 0, 0
+    local matchSrvArr = AreaBattleDB.GetMatchSrvArr()
+    for k, srvTb in ipairs(matchSrvArr or {}) do
+        if table.find(srvTb, sourceServerId) then
+            videoSecondIdx = k
+            leftSrvId = srvTb[1]
+            rightSrvId = srvTb[2]
+            break
+        end
+    end
+
+    -- 本轮没有参加活动
+    if videoSecondIdx == 0 then
+        msgData.errCode = -3
+        return InnerMsg.sendMsg(fd, msgData)
+    end
+
+
+    local serverList = AreaBattleDB.GetServerList()
+    if serverList[leftSrvId] then
+        msgData.srvInfo.leftSrvId = leftSrvId
+        msgData.srvInfo.leftWinTimes = serverList[leftSrvId].winTimes or 0
+        msgData.srvInfo.leftSrvPower = calcSrvPower(serverList[leftSrvId].playerInfoArr)
+    end
+
+    if serverList[rightSrvId] then
+        msgData.srvInfo.rightSrvId = rightSrvId
+        msgData.srvInfo.rightWinTimes = serverList[rightSrvId].winTimes or 0
+        msgData.srvInfo.rightSrvPower = calcSrvPower(serverList[rightSrvId].playerInfoArr)
+    end
+
+
+    local videoArr = AreaBattleDB.GetSrvVideoShowData(videoSecondIdx)
+    -- msgData.videoShowData = videoArr
+
+    for _, v in ipairs(videoArr) do
+        if (v.atkData and v.atkData.uuid == msg.playerUuid) or (v.defenerData and v.defenerData.uuid == msg.playerUuid) then
+            table.insert(msgData.videoShowData, 1, v)
+        else
+            msgData.videoShowData[#msgData.videoShowData+1] = v
+        end
+
+    end
+
+    InnerMsg.sendMsg(fd, msgData)
+end
+
+---------------------------------------------------------------------------------------------
+
+
+function oneMin()
+    if _G.is_middle ~= true then return end
+
+    if not isOpen() then
+        return
+    end
+
+    -- 与 onHour() 处理错开
+    if Util.getMin() == 0 then
+        return
+    end
+
+    local now = os.time()
+    local toDayStartTime = getTodayStartTime()
+
+    -- 活动第一天, 当前时间 >= 开启时间
+    if wDay == AreaBattleDefine.OPEN_WDAY_AREA[1] then
+        earlyHanle()
+    end
+
+    -- 活动最后一天, 当前时间 < 活动结束时间
+    if wDay == AreaBattleDefine.OPEN_WDAY_AREA[2] then
+
+        earlyHanle()
+
+        local stateDB = AreaBattleDB.GetState()
+        -- local nowRoundStartTi = AreaBattleDB.GetNowRoundStartTi()
+
+        -- 当前处于准备阶段, 但是当前时间 >= 对战开始时间, 则进入对战阶段
+        if now >= (toDayStartTime + AreaBattleDefine.BATTLE_STATE_START_SEC) and stateDB == AreaBattleDefine.STATE_PREPARE then
+            -- 防止某些情况下,进入准备阶段后普通服数据还没上传完就进入对战阶段
+            local upLoadStartTi = AreaBattleDB.GetUpLoadStartTi()
+            if now - upLoadStartTi > AreaBattleDefine.BATTLE_DATA_TIME then
+
+                -- 重启跨服后导致战斗数据缓存没了,则重新获取。 -- 新逻辑: 每次进入战斗阶段时才让普通服上传玩家战斗数据
+                if not next(battleDataCache) then
+                    if #requestArr == 0 then
+                        return requestPlayerBattleData()
+                    end
+                end
+
+                -- 处于请求战斗数据过程中, 等请求完再进入战斗
+                if #requestArr > 0 then
+                    return
+                end
+
+                AreaBattleDB.UpdateState(AreaBattleDefine.STATE_BATTLE)
+                BattleStageHandle()
+                return
+            end
+        end
+
+        -- 当前时间 >= 发奖时间
+        if now >= (toDayStartTime + AreaBattleDefine.END_STATE_START_SEC) and stateDB == AreaBattleDefine.STATE_AWARD then
+            AwardPrizesHandle()
+            AreaBattleDB.UpdateState(AreaBattleDefine.STATE_END)
+        end
+    end
+end
+
+function onHour(hour)
+    if _G.is_middle ~= true then return end
+
+    if hour == 0 or not wDay then
+        updateWDay()
+    end
+
+    if not table.find(AreaBattleDefine.OPEN_WDAY_AREA, wDay) then
+        return
+    end
+
+    -- 对战阶段
+    if wDay == AreaBattleDefine.OPEN_WDAY_AREA[2] and hour >= 12 then
+        local now = os.time()
+        local stateDB = AreaBattleDB.GetState()
+        -- local nowRoundStartTi = AreaBattleDB.GetNowRoundStartTi()
+        local upLoadStartTi = AreaBattleDB.GetUpLoadStartTi()
+
+        -- 防止某些情况下,进入准备阶段后,普通服数据还没上传完就进入对战阶段
+        if stateDB == AreaBattleDefine.STATE_PREPARE and (now - upLoadStartTi > AreaBattleDefine.BATTLE_DATA_TIME) then
+
+            -- 重启跨服后导致战斗数据缓存没了,则重新获取。-- 新逻辑: 每次进入战斗阶段时才让普通服上传玩家战斗数据
+            if not next(battleDataCache) then
+                -- 可能存在响应比较慢的情况,保证只执行一次 requestPlayerBattleData
+                if #requestArr == 0 then
+                    return requestPlayerBattleData()
+                end
+            end
+
+            -- 处于请求战斗数据过程中, 等请求完再进入战斗
+            if #requestArr > 0 then
+                return
+            end
+
+            AreaBattleDB.UpdateState(AreaBattleDefine.STATE_BATTLE)
+            BattleStageHandle()
+        end
+    end
+
+    -- 发奖阶段
+    if wDay == AreaBattleDefine.OPEN_WDAY_AREA[2] and hour >= 22 then
+        local stateDB = AreaBattleDB.GetState()
+        if stateDB == AreaBattleDefine.STATE_AWARD then
+            AwardPrizesHandle()
+            AreaBattleDB.UpdateState(AreaBattleDefine.STATE_END)
+        end
+    end
+end
+
+
+-- 通知普通服发奖
+function BrocastServer(srvTb)
+    for fd, notifyInfo in pairs(srvTb) do
+        NotifySrvAwardPrizes(fd, notifyInfo)
+    end
+end
+
+-- 分批次通知普通服
+function BatchServer()
+    local matchSrvArr = AreaBattleDB.GetMatchSrvArr()
+    if not matchSrvArr or not next(matchSrvArr) then
+        return
+    end
+
+    local len, delay_sec = 0, 0
+    local srvTb = {}
+    local serverList = AreaBattleDB.GetServerList()
+    for serverId, serverInfo in pairs(serverList or {}) do
+        local fd = MiddleManager.getFDBySvrIndex(serverId)
+        if fd then
+            len = len + 1
+            local notifyInfo = genNotifyInfo(serverInfo)
+            srvTb[fd] = notifyInfo
+        end
+
+        if len >= AreaBattleDefine.BATCH_MAX_SRV_NUM then
+            delay_sec = delay_sec + 5
+            Timer.addLater(delay_sec, BrocastServer, srvTb)
+            srvTb = {}
+            len = 0
+        end
+    end
+
+    if len > 0 then
+        delay_sec = delay_sec + 5
+        Timer.addLater(delay_sec, BrocastServer, srvTb)
+    end
+end
+
+-- 发奖
+function AwardPrizesHandle()
+    genLog()
+    BatchServer()
+end
+
+
+-- 开始战斗
+function StartBattle()
+    for firstIdx, battleDList in pairs(battleDataCache) do
+        for secondIdx, playerBattleData in pairs(battleDList) do
+            local attackerInfo = playerBattleData.attackerInfo
+            local defenerInfo = playerBattleData.defenerInfo
+
+            local args = {
+                isWin = 0,
+                attackerServerId = "",
+                attackerUuid = "",
+                defenerServerId = "",
+                defenerUuid = ""
+            }
+
+            if attackerInfo and defenerInfo then -- 正常情况
+                args.attackerServerId = attackerInfo.serverId
+                args.attackerUuid = attackerInfo.playerUuid
+                args.defenerServerId = defenerInfo.serverId
+                args.defenerUuid = defenerInfo.playerUuid
+                args.videoSecondIdx = firstIdx
+
+                -- CombatLogicCS.combatBegin(attackerInfo.battleData, defenerInfo.battleData, CombatDefine.COMBAT_TYPE33, FightEnd, args)
+                local ok, err = pcall(CombatLogicCS.combatBegin, attackerInfo.battleData, defenerInfo.battleData, CombatDefine.COMBAT_TYPE33, FightEnd, args)
+                if not ok then
+                    local str = string.format("BattleErr, firstIdx: %d, secondIdx: %d, attackerSrvId: %d, defenerSrvId: %d, attackerUuid: %s, defenerUuid: %s, err: %s", 
+                    firstIdx, secondIdx, args.attackerServerId, args.defenerServerId, args.attackerUuid, args.defenerUuid, err)
+                    writeLog(str)
+                end
+
+            elseif attackerInfo or defenerInfo then
+                -- 有一方战斗数据异常, 则跳过战斗,有战斗数据的一方胜利
+                local errPlayerIdx = 1
+                if attackerInfo then
+                    args.isWin = 1
+                    args.attackerServerId = attackerInfo.serverId
+                    args.attackerUuid = attackerInfo.playerUuid
+
+                    local srvId, playerUuid = getBattleObjInfo(firstIdx, secondIdx, 2)
+                    args.defenerServerId = srvId
+                    args.defenerUuid = playerUuid
+
+                    errPlayerIdx = 2
+                else
+                    local srvId, playerUuid = getBattleObjInfo(firstIdx, secondIdx, 1)
+                    args.attackerServerId = srvId
+                    args.attackerUuid = playerUuid
+
+                    args.isWin = 0
+                    args.defenerServerId = defenerInfo.serverId
+                    args.defenerUuid = defenerInfo.playerUuid
+                end
+
+                updateDBBattleResult(args)
+
+                local str = string.format("BattleDataERR,Err Identity: %d, firstIdx: %d, secondIdx: %d", errPlayerIdx, firstIdx, secondIdx)
+                writeLog(str)
+            end
+        end
+    end
+
+    AreaBattleDB.UpdateState(AreaBattleDefine.STATE_AWARD)
+
+    battleDataCache = {}
+end
+
+-- 外部调用
+-- 收到玩家的战斗数据后, 进行缓存
+function BattleDataHanle(msg)
+    if msg.errCode == 1 then
+        local extraArgs = msg.extraArgs
+        local firstIdx = extraArgs.firstIdx
+        local secondIdx = extraArgs.secondIdx
+        local identity = extraArgs.identity
+
+        battleDataCache[firstIdx] = battleDataCache[firstIdx] or {}
+        battleDataCache[firstIdx][secondIdx] = battleDataCache[firstIdx][secondIdx] or {}
+        local targetTb = battleDataCache[firstIdx][secondIdx]
+
+
+        local playerBattleData = nil
+        if identity == 1 then
+            if not targetTb.attackerInfo then
+                targetTb.attackerInfo = {}
+                playerBattleData = targetTb.attackerInfo
+            end
+        end
+
+        if identity == 2 then
+            if not targetTb.defenerInfo then
+                targetTb.defenerInfo = {}
+                playerBattleData = targetTb.defenerInfo
+            end
+        end
+
+        if playerBattleData then
+            -- playerBattleData.errCode = errCode
+            playerBattleData.serverId = extraArgs.serverId
+            playerBattleData.playerUuid = extraArgs.playerUuid
+            playerBattleData.battleData = {
+                objList = msg.objList,
+                helpList = msg.helpList,
+                roleBase = msg.roleBase,
+                formation = msg.formation,
+                jiBan = msg.jiBan,
+                elfList = msg.elfList,
+            }
+        end
+    end
+
+    -- 开始进入战斗
+    -- StartBattle()
+end
+
+-- 外部调用, 来自本模块的战斗结束后的回调函数
+function FightEnd(result, combatType, combatInfo, extraArgs)
+    if result == CombatDefine.RESULT_WIN then
+        extraArgs.isWin = 1
+    end
+
+    updateDBBattleResult(extraArgs)
+
+    combatInfo.time = os.time()
+    CombatVideo.SaveCombatVideo(CombatVideo.VIDEOTYPE_AREABATTLE, combatInfo, extraArgs.videoSecondIdx)
+end

+ 245 - 0
script/module/areaBattle/AreaBattleDB.lua

@@ -0,0 +1,245 @@
+-- 战区争霸(DB)
+
+local LuaMongo = _G.lua_mongo
+local DB = require("common.DB")
+local Log = require("common.Log")
+local AreaBattleDefine = require("areaBattle.AreaBattleDefine")
+local CombatVideo = require("combat.CombatVideo")
+local CombatDefine = require("combat.CombatDefine")
+
+local dBUpdate = {_id=nil}
+local dBUpdateField = {}
+
+-- 用于展示的简单录像数据
+VideoShowCache = {}
+
+-- DB
+AreaBattleData = nil
+-- {
+--     state = 1,
+--     joinSrvArr = {serverId1, serverId2, serverId3}, -- 参加活动的服务器列表
+--     matchSrvArr = { {serverId1, serverId3}, {serverId2, serverId4}  }, -- 匹配成功的服务器列表
+--     nowRoundStartTi = nil, -- 本轮活动开启时间
+--     upLoadStartTi = nil,   -- 玩家战斗数据上传时间,
+
+--     serverList = {    -- 服务器信息列表
+--         [serverId] = {
+--             serverId = serverId,
+--             winTimes = 0,
+--             defeatTimes = 0,
+--             winPlayerArr = {playerUuid1, playerUuid2,},
+--             playerInfoArr = {
+--                 {
+--                     uuid = uuid,
+--                     power = power,
+--                     name = name,
+--                     head = head,
+--                     headFrame = headFrame,
+--                 },
+--             },
+--         },
+--     }
+-- }
+
+local function initData()
+    AreaBattleData = {}
+    AreaBattleData.state = AreaBattleDefine.STATE_END
+    AreaBattleData.joinSrvArr = {}
+    AreaBattleData.matchSrvArr = {}
+    AreaBattleData.serverList = {}
+
+    LuaMongo.insert(DB.db_area_battle, AreaBattleData)
+end
+
+local function resetData()
+    AreaBattleData.state = AreaBattleDefine.STATE_END
+    AreaBattleData.joinSrvArr = {}
+    AreaBattleData.matchSrvArr = {}
+    AreaBattleData.serverList = {}
+    AreaBattleData.nowRoundStartTi = os.time()
+    AreaBattleData.upLoadStartTi = nil
+
+    dBUpdate._id = AreaBattleData._id
+    LuaMongo.update(DB.db_area_battle, dBUpdate, AreaBattleData)
+end
+
+local function loadData()
+    LuaMongo.find(DB.db_area_battle)
+
+    local data = {}
+    if LuaMongo.next(data) then
+        AreaBattleData = data
+    else
+        initData()
+    end
+end
+
+-- 修改db单个字段
+local function updateValue(key, value)
+	if not key then return end
+
+    if value then
+		dBUpdateField["$set"] = {[key]=value}
+		dBUpdateField["$unset"] = nil
+	else
+		dBUpdateField["$set"] = nil
+		dBUpdateField["$unset"] = {[key]=1}
+	end
+
+	dBUpdate._id = AreaBattleData._id
+	LuaMongo.update(DB.db_area_battle, dBUpdate, dBUpdateField)
+end
+
+-- 生成录像数据中的英雄展示数据
+local function genObjShowInfo(net, playerData, posArr, objList)
+    net.name = playerData.name
+    net.power = playerData.zhandouli
+    net.head = playerData.head
+    net.headFrame = playerData.headFrame
+    net.playerLv = playerData.lv
+    net.uuid = playerData.uuid
+    net.heroList = {}
+
+    local len = 0
+    for _,pos in ipairs(posArr) do
+        local grid = objList and objList[pos]
+        if grid and grid.id ~= 0 then
+            len = len + 1
+            net.heroList[len] = {
+                heroId = grid.id,
+                heroColor = grid.quality or 0,
+                heroStar = grid.star or 0,
+                heroLv = grid.lv or 0,
+                heroCamp = grid.camp or 999
+            }
+        end
+    end
+end
+
+-- 生成某个服的录像展示数据
+local function genSrvVideoSHowData(videoSecondIdx)
+    local videoArr = CombatVideo.getCombatVideosByType(CombatVideo.VIDEOTYPE_AREABATTLE, videoSecondIdx)
+    if #videoArr == 0 then
+        return
+    end
+
+    VideoShowCache[videoSecondIdx] = {}
+
+    for k, videoInfo in ipairs(videoArr) do
+        local combatInfo = videoInfo.combatInfo
+        VideoShowCache[videoSecondIdx][k] = VideoShowCache[videoSecondIdx][k] or {}
+        local videoData = VideoShowCache[videoSecondIdx][k]
+
+        videoData.atkData = {}
+        genObjShowInfo(videoData.atkData, combatInfo.attacker, CombatDefine.SIDE2POS[CombatDefine.ATTACK_SIDE], combatInfo.objList)
+
+        videoData.defenerData = {}
+        genObjShowInfo(videoData.defenerData, combatInfo.defender, CombatDefine.SIDE2POS[CombatDefine.DEFEND_SIDE], combatInfo.objList)
+
+        videoData.atkFormation = combatInfo.atkFormation
+        videoData.defenerFormation = combatInfo.defFormation
+        videoData.round = combatInfo.result.round
+        videoData.maxRound = combatInfo.maxRound
+        videoData.time = combatInfo.time
+        videoData.videoUuid = videoInfo._id
+        videoData.result = combatInfo.isWin == true and 1 or 0
+    end
+end
+
+
+
+function initAfterStart()
+    if _G.is_middle ~= true then return end
+    loadData()
+end
+
+function ResetData()
+    resetData()
+end
+
+
+
+
+function GetNowRoundStartTi()
+    return AreaBattleData and AreaBattleData.nowRoundStartTi or 0
+end
+
+
+function GetUpLoadStartTi()
+    return AreaBattleData and AreaBattleData.upLoadStartTi or 0
+end
+
+function UpdateUpLoadStartTi(newUpLoadStartTi)
+    AreaBattleData = AreaBattleData or {}
+    AreaBattleData.upLoadStartTi = newUpLoadStartTi
+    updateValue("upLoadStartTi", newUpLoadStartTi)
+end
+
+
+
+function GetState()
+    return AreaBattleData and AreaBattleData.state or AreaBattleDefine.STATE_END
+end
+
+function UpdateState(newState)
+    AreaBattleData = AreaBattleData or {}
+    AreaBattleData.state = newState
+    updateValue("state", newState)
+
+    if newState == AreaBattleDefine.STATE_PREPARE then
+        local now = os.time()
+
+        AreaBattleData.nowRoundStartTi = now
+        updateValue("nowRoundStartTi", AreaBattleData.nowRoundStartTi)
+    end
+end
+
+
+function GetJoinSrvArr()
+    return AreaBattleData.joinSrvArr
+end
+
+function UpdateJoinSrvArr(newJoinSrvArr)
+    AreaBattleData = AreaBattleData or {}
+    AreaBattleData.joinSrvArr = newJoinSrvArr
+    updateValue("joinSrvArr", newJoinSrvArr)
+end
+
+
+function GetServerList()
+    return AreaBattleData.serverList
+end
+
+function UpdateServerList(newServerList)
+    AreaBattleData = AreaBattleData or {}
+    AreaBattleData.serverList = newServerList
+    updateValue("serverList", newServerList)
+end
+
+
+function GetMatchSrvArr()
+    return AreaBattleData.matchSrvArr
+end
+
+function UpdateMatchSrvArr(newMatchSrvArr)
+    AreaBattleData = AreaBattleData or {}
+    AreaBattleData.matchSrvArr = newMatchSrvArr
+    updateValue("matchSrvArr", newMatchSrvArr)
+end
+
+
+function GetSrvVideoShowData(videoSecondIdx)
+    if not videoSecondIdx then
+        return
+    end
+
+    if not VideoShowCache[videoSecondIdx] then
+        genSrvVideoSHowData(videoSecondIdx)
+    end
+
+    return VideoShowCache[videoSecondIdx]
+end
+
+function ResetVideoShowCache()
+    VideoShowCache = {}
+end

+ 60 - 0
script/module/areaBattle/AreaBattleDefine.lua

@@ -0,0 +1,60 @@
+
+STATE_END = 0       -- 休战阶段标识
+STATE_PREPARE = 1   -- 准备阶段标识
+STATE_BATTLE = 2    -- 战斗阶段标识
+STATE_AWARD = 3     -- 发奖阶段标识
+
+
+
+OPEN_WDAY_AREA = {7, 1} -- 一周中活动开启的时间范围
+
+
+-- 准备
+PREPARE_STATE_START_SEC = 1800          -- 30*60, 用于与当天0点时间戳计算准备阶段的开始时间
+
+-- 战斗
+BATTLE_STATE_START_SEC = 43200          -- 12*60*60, 用于与当天0点时间戳计算战斗阶段的开始时间
+
+-- 休战
+END_STATE_START_SEC = 79200             -- 22*60*60, 用于与当天0点时间戳计算休战阶段的开始时间
+
+
+
+
+JOIN_BATTLE_MAX_CNT = 15        -- 每个服最多参战人数
+
+BATCH_MAX_SRV_NUM = 10          -- 发奖时,10个服务器为一批
+
+SERVER_DATA_TIME = 120         -- 准备阶段, 普通服上传排行榜前15名玩家数据需要2分钟
+
+BATTLE_DATA_TIME = 300          -- 普通服上传玩家战斗数据需要5分钟。(每批请求20个玩家,每批延迟2s, 最多100个服同时对战)
+
+
+
+SRV_START_IDX = 810537  -- 服务器ID的起始值
+SRV_NAME_STR = "服"
+
+
+
+MAIL_FAIL_TAG = "fail"
+MAIL_SUCC_TAG = "succ"
+
+AWARD_TYPE1 = 1 -- 战胜服个人战胜奖励
+AWARD_TYPE2 = 2 -- 战胜服个人战败奖励
+AWARD_TYPE3 = 3 -- 战胜服全服奖励
+
+AWARD_TYPE4 = 4 -- 战败服个人战胜奖励
+AWARD_TYPE5 = 5 -- 战败服个人战败奖励
+AWARD_TYPE6 = 6 -- 战败服全服奖励
+
+-- 奖励类型 —— 邮件ID映射表
+AWARDTYPE2MAILID = {
+    [AWARD_TYPE1] = 7026,
+    [AWARD_TYPE2] = 7027,
+    [AWARD_TYPE3] = 7024,
+    [AWARD_TYPE4] = 7028,
+    [AWARD_TYPE5] = 7029,
+    [AWARD_TYPE6] = 7025,
+}
+
+GET_BATTLE_MAX_CNT_TIMES = 20  -- 一次最多请求30名玩家的战斗数据

+ 600 - 0
script/module/areaBattle/AreaBattleNS.lua

@@ -0,0 +1,600 @@
+-- 战区争霸(普通服)
+
+local Config = require("Config")
+local Msg = require("core.Msg")
+local Lang = require("common.Lang")
+local ObjHuman = require("core.ObjHuman")
+local Broadcast = require("broadcast.Broadcast")
+local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
+local RoleSystemDefine = require("roleSystem.RoleSystemDefine")
+local CombatDefine = require("combat.CombatDefine")
+local RoleDBLogic = require("role.RoleDBLogic")
+local CombatPosLogic = require("combat.CombatPosLogic")
+local CombatLogic = require("combat.CombatLogic")
+local MailExcel = require("excel.mail")
+local Util = require("common.Util")
+local InnerMsg = require("core.InnerMsg")
+local RoleHeadLogic = require("role.RoleHeadLogic")
+local MailManager = require("mail.MailManager")
+local AreaBattleConfig = require("excel.areaBattle").reward
+local Log = require("common.Log")
+local Timer = require("core.Timer")
+local CommonDB = require("common.CommonDB")
+local RoleSystemExcel = require("excel.roleSystem")
+local Grid = require("bag.Grid")
+local BillboardLogic = require("billboard.BillboardLogic")
+local BillboardDefine = require("billboard.BillboardDefine")
+local AreaBattleDefine = require("areaBattle.AreaBattleDefine")
+
+
+local mailQueue = {
+    uuidArray = {},
+    insertMaxNum = 100, -- 一次最多插入数据库的邮件数量
+    repeatMaxTimes = 3, -- 重试次数
+    repeatTb = {}
+}
+
+-- 检查是否开启
+local function openCheck()
+    local wDay = Util.getWeekDay()
+    if not table.find(AreaBattleDefine.OPEN_WDAY_AREA, wDay) then
+        return false
+    end
+
+    local now = os.time()
+    local toDayStartTime = Util.getDayStartTime(now)
+
+    if wDay == AreaBattleDefine.OPEN_WDAY_AREA[1] and now < (toDayStartTime + AreaBattleDefine.PREPARE_STATE_START_SEC) then
+        return false
+    end
+
+    if wDay == AreaBattleDefine.OPEN_WDAY_AREA[2] and now > (toDayStartTime + AreaBattleDefine.END_STATE_START_SEC) then
+        return false
+    end
+
+    return true
+end
+
+-- 生成符合协议数据结构的奖励数据
+local function populateAwardMsg(msgTb, awardCfg)
+    for idx, itemCfg in ipairs(awardCfg) do
+        msgTb[0] = idx
+        Grid.makeItem(msgTb[idx], itemCfg[1], itemCfg[2])
+    end
+end
+
+-- 生成符合协议数据结构的英雄数据
+local function populateObjMsg(net, data)
+    net.name = data.name or ""
+    net.power = data.power or 0
+    net.head = data.head or 0
+    net.headFrame = data.headFrame or 0
+    net.playerLv = data.playerLv or 90
+
+    net.heroList[0] = 0
+    for k, heroInfo in ipairs(data.heroList) do
+        net.heroList[0] = k
+        net.heroList[k].heroId = heroInfo.heroId or 1001
+        net.heroList[k].heroColor = heroInfo.heroColor or 0
+        net.heroList[k].heroStar = heroInfo.heroStar or 1
+        net.heroList[k].heroLv = heroInfo.heroLv or 1
+        net.heroList[k].heroCamp = heroInfo.heroCamp or 999
+    end
+end
+
+
+local function sendMail(mailId, receiverUuid, itemArray)
+    if not mailId or not receiverUuid then
+        return
+    end
+
+    local mailCfg = MailExcel.mail[mailId]
+    local content = mailCfg.content
+    MailManager.add(MailManager.SYSTEM, receiverUuid, mailCfg.title, content, itemArray, mailCfg.senderName or "GM")
+end
+
+local function writeLog(logStr)
+    Log.write(Log.LOGID_OSS_AREABATTLE_AWARD, logStr)
+end
+
+
+function mailQueue:add(playerInfo)
+    table.insert(self.uuidArray, playerInfo)
+end
+
+function mailQueue:clear()
+    Util.cleanTable(self.uuidArray)
+    Util.cleanTable(self.repeatTb)
+end
+
+function mailQueue:insertDB()
+    local maxNum = math.min(self.insertMaxNum, #self.uuidArray)
+
+    for i=1, maxNum do
+        local resTag = AreaBattleDefine.MAIL_SUCC_TAG
+        local playerInfo = table.remove(self.uuidArray)
+        local uuid = playerInfo[1]
+        local awardType = playerInfo[3]
+
+        local ok, err = pcall(sendMail, AreaBattleDefine.AWARDTYPE2MAILID[awardType], uuid, playerInfo[2])
+        if not ok then
+            if not self.repeatTb[uuid] or self.repeatTb[uuid] < self.repeatMaxTimes then
+                mailQueue:add(playerInfo)
+                self.repeatTb[uuid] = (self.repeatTb[uuid] or 0) + 1
+            end
+
+            resTag = AreaBattleDefine.MAIL_FAIL_TAG
+        end
+
+        local str = string.format("Result: %s, playerUuid: %s, AwardType: %d, insertErrTimes: %d, errInfo: %s",
+                    resTag, uuid, awardType, self.repeatTb[uuid] or 0, err)
+
+        writeLog(str)
+    end
+
+    if #self.uuidArray > 0 then
+        Timer.addLater(3, mailQueue.insertDB, mailQueue)
+    end
+end
+
+local function insertPlayerAward(playerArr, battlePlyerArr, awardArr, awardType)
+    local len = #playerArr
+    for _, uuid in pairs(battlePlyerArr or {}) do
+        len = len + 1
+        local item = {}
+        for idx, itemInfo in ipairs(awardArr) do
+            item[idx] = {itemInfo[1], itemInfo[2]}
+        end
+        playerArr[len] = {uuid, item, awardType}
+    end
+end
+
+local function genPlayerAwardArray(srvBattleRes)
+    local DataCache = require("core.DataCache")
+    local playerUidList = DataCache.Get_PlayerUuidList()
+
+    local winAwardType, defeateAwardType, normalAwardType = AreaBattleDefine.AWARD_TYPE1, AreaBattleDefine.AWARD_TYPE2, AreaBattleDefine.AWARD_TYPE3
+    local battleWinAwward, battleDefeatAward, normalAward = AreaBattleConfig[1].winAward1, AreaBattleConfig[1].winAward2, AreaBattleConfig[1].winAward3
+    if srvBattleRes.isWin == 0 then
+        winAwardType, defeateAwardType, normalAwardType = AreaBattleDefine.AWARD_TYPE4, AreaBattleDefine.AWARD_TYPE5, AreaBattleDefine.AWARD_TYPE6
+        battleWinAwward, battleDefeatAward, normalAward = AreaBattleConfig[1].defeatAward1, AreaBattleConfig[1].defeatAward2, AreaBattleConfig[1].defeatAward3
+    end
+
+    local len = 0
+    local playerAwardArray = {}
+
+    insertPlayerAward(playerAwardArray, srvBattleRes.winPlayerArr, battleWinAwward, winAwardType)
+    insertPlayerAward(playerAwardArray, srvBattleRes.winPlayerArr, normalAward, normalAwardType)
+
+    insertPlayerAward(playerAwardArray, srvBattleRes.defeatPlayerArr, battleDefeatAward, defeateAwardType)
+    insertPlayerAward(playerAwardArray, srvBattleRes.defeatPlayerArr, normalAward, normalAwardType)
+
+
+    len = #playerAwardArray
+    for uuid in pairs(playerUidList) do
+        if not table.find(srvBattleRes.winPlayerArr, uuid) and not table.find(srvBattleRes.defeatPlayerArr, uuid) then
+            len = len + 1
+            local item = {}
+            for idx, itemInfo in ipairs(normalAward) do
+                item[idx] = {itemInfo[1], itemInfo[2]}
+            end
+
+            playerAwardArray[len] = {uuid, item, normalAwardType}
+        end
+    end
+
+
+    if len == 0 then
+        return
+    end
+
+    return playerAwardArray
+end
+
+
+-- 开服天数检查
+local function checkSvrOpenDays()
+    local openDay = CommonDB.getServerOpenDay()
+    local ctrlCfg = RoleSystemExcel.roleSystem[RoleSystemDefine.ROLE_SYS_ID_1306]
+    if ctrlCfg.openSvrDay > openDay then
+        return false
+    end
+
+    return true
+end
+
+-- 单个英雄数据
+-- local function getHeroInfo(human, targetHeroUuid)
+--     local HeroLogic = require("hero.HeroLogic")
+--     local heroGrid = HeroLogic.getHeroGridByUuid(human, targetHeroUuid)
+--     if heroGrid then
+--         local heroCfg = HeroExcel.hero[heroGrid.id]
+--         local heroInfo = {
+--             heroUuid = targetHeroUuid,
+--             heroStar = heroGrid.star,
+--             heroLevel = heroGrid.lv,
+--             heroCamp =  heroGrid.camp or heroCfg.camp,
+--             heroBody = heroCfg.body
+--         }
+
+--         return heroInfo
+--     end
+-- end
+
+-- 获取上阵英雄数据
+-- local function getHeroListInfo(human, targetHeroUuid)
+--     local len = 0
+--     local heroArr = {}
+
+--     local heroList = CombatPosLogic.getCombatHeros(human, CombatDefine.COMBAT_TYPE32)
+--     if not next(heroList) then
+--         heroList = CombatPosLogic.getCombatHeros(human, CombatDefine.COMBAT_TYPE1)
+--     end
+
+--     for _, heroUuid in pairs(heroList) do
+--         if not targetHeroUuid or targetHeroUuid == heroUuid then
+--             len = len + 1
+--             heroArr[len] = getHeroInfo(human, heroUuid)
+--         end
+--     end
+
+--     if len == 0 then
+--         return
+--     end
+--     return heroArr
+-- end
+
+-- 生成玩家展示数据
+local function genPlayerShowData(playerUuid)
+    local human = ObjHuman.onlineUuid[playerUuid]
+    if not human then
+        local db = RoleDBLogic.getDb(playerUuid)
+        if not db then
+            return
+        end
+
+        human = {}
+        human.db = db
+    end
+
+    local showInfo = {}
+    showInfo.uuid = playerUuid
+    showInfo.power = human.db.zhandouli
+    showInfo.name = human.db.name
+
+    showInfo.head = RoleHeadLogic.getRoleAppearance(human, RoleHeadLogic.HEAD_TYPE_1)
+    showInfo.headFrame = RoleHeadLogic.getRoleAppearance(human, RoleHeadLogic.HEAD_TYPE_2)
+    -- showInfo.heroList = getHeroListInfo(human)
+    return showInfo
+end
+
+-- 生成本服参战列表
+local function genJoinBattleArray()
+    local rankList = BillboardLogic.GetRankList(BillboardDefine.TYPE_ZHANDOULI)
+    if not rankList then
+        return
+    end
+
+    local len = 0
+    local joinBattleArray = {}
+    for _, PlayerData in ipairs(rankList) do
+        if len >= AreaBattleDefine.JOIN_BATTLE_MAX_CNT then
+            break
+        end
+
+        local pkayerInfo = genPlayerShowData(PlayerData.uuid)
+        if pkayerInfo then
+            len = len + 1
+            joinBattleArray[len] = pkayerInfo
+        end
+    end
+
+    table.shuffle(joinBattleArray)
+
+    return joinBattleArray
+end
+
+
+function getActState(human)
+    local state, leftTime = 1, 0
+
+    if not openCheck() then
+        state = 0
+    end
+
+    return state, leftTime
+end
+
+function isOpen(human)
+    return RoleSystemLogic.isOpen(human, RoleSystemDefine.ROLE_SYS_ID_1306)
+end
+
+function getCombatObjList(human, side, args, combatType)
+    if side == CombatDefine.ATTACK_SIDE and not human then return end
+
+    if side == CombatDefine.DEFEND_SIDE and human then
+        return
+    end
+
+    if not human then
+        local uuid = args[1]
+        local db = RoleDBLogic.getDb(uuid)
+        if not db then
+            return
+        end
+        human = {}
+        human.db = db
+    end
+
+    local heroList = CombatPosLogic.getCombatHeros(human, combatType)
+    if next(heroList) then
+        return CombatLogic.getHumanObjList(human, combatType)
+    else
+        return CombatLogic.getHumanObjList(human, CombatDefine.COMBAT_TYPE1)
+    end
+end
+
+
+
+
+--------------------------------------------N2C----------------------------------------------------
+
+-- 加入战斗
+local function joinBattle()
+    local joinBattleArray = genJoinBattleArray()
+    -- if not joinBattleArray or #joinBattleArray <= 0 then
+    --     return
+    -- end
+    local msgData = InnerMsg.lw.LW_AREABATTLE_JOIN_BATTLE
+    msgData.sourceServerId = Config.SVR_INDEX
+    msgData.joinBattleArray = joinBattleArray or {}
+    InnerMsg.sendMsg(0, msgData)
+end
+
+-- 获取活动基础信息
+function GetBaseInfo(human)
+    local msgData = InnerMsg.lw.LW_AREABATTLE_BASEINFO_QUERY
+    msgData.sourceServerId = Config.SVR_INDEX
+    msgData.playerUuid = human.db._id
+    InnerMsg.sendMsg(0, msgData)
+end
+
+-- 获取本服参战玩家列表
+function GetJoinPlayerArr(human)
+    -- if not openCheck() then
+    --     local msgRet = Msg.gc.GC_AREABATTLE_JOINPLAYER_QUERY
+    --     msgRet.errCode = -2
+    --     msgRet.isJoin = 0
+    --     msgRet.playerArray[0] = 0
+    --     return Msg.send(msgRet, human.fd)
+    -- end
+
+    local msgData = InnerMsg.lw.LW_AREABATTLE_JOINPLAYER_QUERY
+    msgData.sourceServerId = Config.SVR_INDEX
+    msgData.playerUuid = human.db._id
+    InnerMsg.sendMsg(0, msgData)
+end
+
+-- 获取区服匹配列表(两两匹配)
+function GetMatchList(human)
+    -- if not openCheck() then
+    --     local msgRet = Msg.gc.GC_AREABATTLE_MATCHLIST_QUERY
+    --     msgRet.errCode = -2
+    --     msgRet.matchList[0] = 0
+    --     return Msg.send(msgRet, human.fd)
+    -- end
+    local msgData = InnerMsg.lw.LW_AREABATTLE_MATCHLIST_QUERY
+    msgData.sourceServerId = Config.SVR_INDEX
+    msgData.playerUuid = human.db._id
+    InnerMsg.sendMsg(0, msgData)
+end
+
+--获取录像
+function GetCombatVideo(human)
+    -- if not openCheck() then
+    --     local msgRet = Msg.gc.GC_GODSAREA_QUERY_COMBATVIDEO
+    --     msgRet.errCode = -2
+    --     msgRet.leftWinTimes = 0
+    --     msgRet.rightWinTimes = 0
+    --     msgRet.leftSrvName = ""
+    --     msgRet.leftSrvPower = 0
+    --     msgRet.rightSrvName = ""
+    --     msgRet.rightSrvPower = 0
+    --     msgRet.videoList[0] = 0
+    --     return Msg.send(msgRet, human.fd)
+    -- end
+    local msgData = InnerMsg.lw.LW_AREABATTLE_VIDEOSHOW_QUERY
+    msgData.sourceServerId = Config.SVR_INDEX
+    msgData.playerUuid = human.db._id
+    InnerMsg.sendMsg(0, msgData)
+end
+
+-- 获取奖励列表
+function GetAwardInfo(human)
+    local msgRet = Msg.gc.GC_AREABATTLE_REWARD_QUERY
+
+    populateAwardMsg(msgRet.winJoinAward, AreaBattleConfig[1].winAward1)
+    populateAwardMsg(msgRet.winJoinAward2, AreaBattleConfig[1].winAward2)
+    populateAwardMsg(msgRet.winNormalAward, AreaBattleConfig[1].winAward3)
+
+    populateAwardMsg(msgRet.defaultJoinAward, AreaBattleConfig[1].defeatAward1)
+    populateAwardMsg(msgRet.defaultJoinAward2, AreaBattleConfig[1].defeatAward2)
+    populateAwardMsg(msgRet.defaultNormalAward, AreaBattleConfig[1].defeatAward3)
+
+    Msg.send(msgRet, human.fd)
+end
+
+
+
+
+--------------------------------------------C2N----------------------------------------------------
+
+-- 收到活动开启通知
+function C2N_BattleStart()
+    if not checkSvrOpenDays() then
+        return
+    end
+    joinBattle()
+end
+
+-- 收到活动基础信息
+function C2N_BaseInfo(msg)
+    local human = ObjHuman.onlineUuid[msg.playerUuid]
+    if not human then
+        return
+    end
+
+    local msgRet = Msg.gc.GC_AREABATTLE_BASEINFO_QUERY
+    msgRet.stage = msg.stage
+    msgRet.startTime = msg.startTime
+    msgRet.endTime = msg.endTime
+    Msg.send(msgRet, human.fd)
+end
+
+-- 收到本服参战玩家列表
+function C2N_JoinPlayerArr(msg)
+    local human = ObjHuman.onlineUuid[msg.playerUuid]
+    if not human then
+        return
+    end
+
+    local msgRet = Msg.gc.GC_AREABATTLE_JOINPLAYER_QUERY
+    msgRet.errCode = msg.errCode
+    msgRet.isJoin = 0
+    msgRet.playerArray[0] = 0
+
+    if msg.errCode == 0 then
+        local playerArray = msg.playerArray
+        table.sort(playerArray, function (a, b)
+            return a.power > b.power
+        end)
+
+        for k, v in ipairs(playerArray) do
+            msgRet.playerArray[0] = k
+            msgRet.playerArray[k].name = v.name
+            msgRet.playerArray[k].power = v.power
+            msgRet.playerArray[k].head = v.head
+            msgRet.playerArray[k].headFrame = v.headFrame
+            msgRet.playerArray[k].isMe = 0
+
+            if v.uuid == msg.playerUuid then
+                msgRet.isJoin = 1
+                msgRet.playerArray[k].isMe = 1
+            end
+        end
+    end
+
+    Msg.send(msgRet, human.fd)
+end
+
+-- 收到本轮活动的区服匹配列表
+function C2N_MatchList(msg)
+    local human = ObjHuman.onlineUuid[msg.playerUuid]
+    if not human then
+        return
+    end
+
+    local msgRet = Msg.gc.GC_AREABATTLE_MATCHLIST_QUERY
+    msgRet.errCode = 0
+    local matchListMsg = msgRet.matchList
+    matchListMsg[0] = 0
+
+    if not next(msg.matchList) then
+        msgRet.errCode = -1
+    else
+        for k, v in ipairs(msg.matchList) do
+            matchListMsg[0] = k
+
+            --for _, srvInfo in ipairs(v) do
+                local leftSrv = v[1]
+                local rightSrv = v[2]
+                matchListMsg[k].leftSrvName = (leftSrv[1] - AreaBattleDefine.SRV_START_IDX) .. AreaBattleDefine.SRV_NAME_STR
+                matchListMsg[k].leftSrvPower = leftSrv[2]
+
+                matchListMsg[k].rightSrvName = (rightSrv[1] - AreaBattleDefine.SRV_START_IDX) .. AreaBattleDefine.SRV_NAME_STR
+                matchListMsg[k].rightSrvPower = rightSrv[2]
+
+                matchListMsg[k].mySrvPos = 0
+                if leftSrv[1] == Config.SVR_INDEX then
+                    matchListMsg[k].mySrvPos = 1
+                elseif rightSrv[1] == Config.SVR_INDEX then
+                    matchListMsg[k].mySrvPos = 2
+                end
+            --end
+        end
+    end
+
+    Msg.send(msgRet, human.fd)
+end
+
+-- 收到本服的战斗录像展示数据
+function C2N_VideoShowData(msg)
+    local human = ObjHuman.onlineUuid[msg.playerUuid]
+    if not human then
+        return
+    end
+
+    local errCode = msg.errCode
+    local msgRet = Msg.gc.GC_AREABATTLE_COMBATVIDEO_QUERY
+    msgRet.errCode = errCode
+    msgRet.leftWinTimes = 0
+    msgRet.rightWinTimes = 0
+    msgRet.leftSrvName = ""
+    msgRet.leftSrvPower = 0
+    msgRet.rightSrvName = ""
+    msgRet.rightSrvPower = 0
+    msgRet.videoList[0] = 0
+    if errCode ~= 0 then
+        return Msg.send(msgRet, human.fd)
+    end
+
+    local srvInfo = msg.srvInfo
+    msgRet.leftWinTimes = srvInfo.leftWinTimes
+    msgRet.rightWinTimes = srvInfo.rightWinTimes
+    msgRet.leftSrvName = (srvInfo.leftSrvId - AreaBattleDefine.SRV_START_IDX) .. AreaBattleDefine.SRV_NAME_STR
+    msgRet.leftSrvPower = srvInfo.leftSrvPower
+    msgRet.rightSrvName = (srvInfo.rightSrvId - AreaBattleDefine.SRV_START_IDX) .. AreaBattleDefine.SRV_NAME_STR
+    msgRet.rightSrvPower = srvInfo.rightSrvPower
+
+    for k, v in ipairs(msg.videoShowData) do
+        msgRet.videoList[0] = k
+        -- msgRet.videoList[k].atkData = v.atkData
+        -- msgRet.videoList[k].defenerData = v.defenerData
+        populateObjMsg(msgRet.videoList[k].atkData, v.atkData)
+        populateObjMsg(msgRet.videoList[k].defenerData, v.defenerData)
+        msgRet.videoList[k].atkFormation = v.atkFormation
+        msgRet.videoList[k].defenerFormation = v.defenerFormation
+        msgRet.videoList[k].round = v.round
+        msgRet.videoList[k].maxRound = v.maxRound
+        msgRet.videoList[k].time = v.time
+        msgRet.videoList[k].videoUuid = v.videoUuid
+        msgRet.videoList[k].result = v.result
+
+        msgRet.videoList[k].myPos = 0
+        if k == 1 then
+            if v.atkData.uuid == msg.playerUuid then
+                msgRet.videoList[k].myPos = 1
+            elseif v.defenerData.uuid == msg.playerUuid then
+                msgRet.videoList[k].myPos = 2
+            end
+        end
+    end
+
+    Msg.send(msgRet, human.fd)
+end
+
+-- 收到给玩家发奖励通知
+function C2N_SendReward(msg)
+    local playerAwardArray = genPlayerAwardArray(msg.srvBattleRes)
+    if not playerAwardArray then
+        return
+    end
+
+    mailQueue:clear()
+
+    for _, playerInfo in ipairs(playerAwardArray) do
+        mailQueue:add(playerInfo)
+    end
+
+    mailQueue:insertDB()
+end

+ 21 - 0
script/module/areaBattle/Handler.lua

@@ -0,0 +1,21 @@
+local AreaBattleNS = require("areaBattle.AreaBattleNS")
+
+function CG_AREABATTLE_BASEINFO_QUERY(human)
+    AreaBattleNS.GetBaseInfo(human)
+end
+
+function CG_AREABATTLE_JOINPLAYER_QUERY(human)
+    AreaBattleNS.GetJoinPlayerArr(human)
+end
+
+function CG_AREABATTLE_MATCHLIST_QUERY(human)
+    AreaBattleNS.GetMatchList(human)
+end
+
+function CG_AREABATTLE_COMBATVIDEO_QUERY(human)
+    AreaBattleNS.GetCombatVideo(human)
+end
+
+function CG_AREABATTLE_REWARD_QUERY(human)
+    AreaBattleNS.GetAwardInfo(human)
+end

+ 115 - 0
script/module/areaBattle/Proto.lua

@@ -0,0 +1,115 @@
+
+local ItemData = require("bag.Proto").ItemData
+
+
+BATTLE_HERO_INFO = {
+    {"heroId",          1,      "int"},      -- 英雄Id
+    {"heroColor",       1,      "byte"},     -- 英雄品质
+    {"heroStar",        1,      "byte"},     -- 英雄星级
+    {"heroLv",          1,      "int"},     -- 英雄等级
+    {"heroCamp",        1,      "int"},     -- 英雄种族
+}
+
+
+JOIN_PLAYER_INFO = {
+    {"name",            1,      "string"},  -- 名字
+    {"power",           1,      "int"},     -- 战力
+    {"head",            1,      "int"},     -- 头像
+    {"headFrame",       1,      "int"},     -- 头像框
+    {"isMe",            1,      "byte"},    -- 是否是自己, 0-不是, 1-是
+}
+
+
+MATCH_INFO = {
+    {"leftSrvName",             1,      "string"},      -- 区服1名字
+    {"leftSrvPower",            1,      "double"},      -- 区服1总战力
+    {"rightSrvName",            1,      "string"},      -- 区服2名字
+    {"rightSrvPower",           1,      "double"},      -- 区服2总战力
+    {"mySrvPos",                1,      "byte"},        -- 本服位置, 0-没有, 1-左边, 2-右边
+}
+
+
+OBJ_INFO ={
+    {"name",            1,      "string"},  -- 名字
+    {"power",           1,      "int"},     -- 战力
+    {"head",            1,      "int"},     -- 头像
+    {"headFrame",       1,      "int"},     -- 头像框
+    {"playerLv",        1,      "int"},     -- 玩家等级
+    {"heroList",        6,      BATTLE_HERO_INFO},  -- 出战英雄信息
+}
+
+-- 录像信息
+AREABATTLE_COMBAT_VIDEO_INFO = {
+    {"atkData",         1,  OBJ_INFO},        -- 攻击方信息
+    {"defenerData",     1,  OBJ_INFO},        -- 防御方信息
+    {"atkFormation",    1,  "int"},           -- 攻击方阵法
+    {"defenerFormation",1,  "int"},           -- 防御方阵法
+    {"round",           1,  "int"},           -- 回合数
+    {"maxRound",        1,  "int"},           -- 最大合数
+    {"time",            1,  "int"},           -- 战斗时间
+    {"videoUuid",       1,  "string"},        -- 录像索引
+    {"result",          1,  "byte"},          -- 战斗结果    1 攻方胜  0 守方胜
+    {"myPos",           1,  "byte"},          -- 玩家在录像中位置, 0-本场战斗玩家没有参加, 1-左边, 2-右边 
+}
+
+
+
+-- 查询活动基本信息
+CG_AREABATTLE_BASEINFO_QUERY = {}
+
+GC_AREABATTLE_BASEINFO_QUERY = {
+    {"stage",           1,              "byte"},            -- 当前阶段, 0-休战, 1-准备, 2- 战斗, 3-发奖
+    {"startTime",       1,              "int"},             -- 本轮活动开始时间
+    {"endTime",         1,              "int"},             -- 本轮活动结束时间
+}
+
+
+
+-- 查询本服参战玩家列表
+CG_AREABATTLE_JOINPLAYER_QUERY = {}
+
+GC_AREABATTLE_JOINPLAYER_QUERY = {
+    {"errCode",         1,              "byte"},            -- 错误码, 0-正常, -1: 本服没有参加, -2:匹配中,稍后再试, -3: 本次比赛轮空
+    {"isJoin",          1,              "byte"},            -- 自己是否参加,0-没有, 1- 参加
+    {"playerArray",     15,             JOIN_PLAYER_INFO},  -- 参战玩家数据
+}
+
+
+
+-- 查询匹配列表
+CG_AREABATTLE_MATCHLIST_QUERY = {}
+
+GC_AREABATTLE_MATCHLIST_QUERY = {
+    {"errCode",         1,              "byte"},            -- 错误码, 0-正常, -1: 暂无匹配列表, -2: 当前处于休战期
+    {"matchList",       100,              MATCH_INFO},      -- 匹配列表
+}
+
+
+
+
+-- 查看本服战斗录像
+CG_AREABATTLE_COMBATVIDEO_QUERY = {}
+
+GC_AREABATTLE_COMBATVIDEO_QUERY = {
+    {"errCode",             1,      "byte"},                    -- 错误码, 0-正常, -1: 暂时没有录像数据, -2: 当前处于休战期, -3:本次比赛轮空
+    {"leftWinTimes",        1,      "byte"},                    -- 进攻方胜利次数
+    {"rightWinTimes",       1,      "byte"},                    -- 防御方胜利次数
+    {"leftSrvName",         1,      "string"},                  -- 区服1名字
+    {"leftSrvPower",        1,      "double"},                  -- 区服1总战力
+    {"rightSrvName",        1,      "string"},                  -- 区服2名字
+    {"rightSrvPower",       1,      "double"},                  -- 区服2总战力
+    {"videoList",           15,     AREABATTLE_COMBAT_VIDEO_INFO},  -- 回放记录列表
+}
+
+
+-- 获取奖励
+CG_AREABATTLE_REWARD_QUERY = {}
+
+GC_AREABATTLE_REWARD_QUERY = {
+    {"winJoinAward",            5,        ItemData},         -- 胜方参与者胜利的奖励
+    {"winJoinAward2",           5,        ItemData},         -- 胜方参与者失败的奖励
+    {"winNormalAward",          5,        ItemData},         -- 胜方全服奖励
+    {"defaultJoinAward",        5,        ItemData},         -- 败方参与者胜利的奖励
+    {"defaultJoinAward2",       5,        ItemData},         -- 败方参与者失败的奖励
+    {"defaultNormalAward",      5,        ItemData},         -- 败方全服奖励
+}

+ 73 - 3
script/module/bag/BagLogic.lua

@@ -64,7 +64,13 @@ function cleanMomentItemList()
 end
 
 function addMomentItemList(human, logType, noSend)
+	if not noSend then
+		noSend = true
+	end
+
 	addItemList(human, ITEM_MOMENT_ADD_LIST, logType, noSend)
+
+	sendListChange(human, ITEM_MOMENT_ADD_LIST)
 	cleanMomentItemList()
 end
 
@@ -146,7 +152,14 @@ function addItem(human, id, cnt, logType, noSend, otherData)
 	end
 
 	local oldCnt = human.db.bag[id] or 0
-	local newCnt = math.min(oldCnt + cnt, ItemDefine.BAG_ITEM_MAX_CNT)
+	-- local newCnt = math.min(oldCnt + cnt, ItemDefine.BAG_ITEM_MAX_CNT)
+
+	local maxNum = ItemDefine.BAG_ITEM_MAX_CNT
+	if id == ItemDefine.ITEM_GREEN_EXP_ID then
+		maxNum = ItemDefine.BAG_ITEM_MAX_JINBI
+	end
+
+	local newCnt = math.min(oldCnt + cnt, maxNum)
 	human.db.bag[id] = newCnt
 
 	if not noSend then
@@ -166,6 +179,11 @@ function addItem(human, id, cnt, logType, noSend, otherData)
     -- 根据道具触发红点
 	checkDotByID(human,id)
 
+	if itemConfig.subType == ItemDefine.ITEM_SUBTYPE_ELF then
+		--print("[addItem] 触发获得精灵")
+		TriggerLogic.PublishEvent(TriggerDefine.EVENT_TYPE_JINGLING_GET, human.db._id, 1, id)
+	end
+
 	return true
 end
 
@@ -299,6 +317,7 @@ function handleEquipAdd(human, itemID, itemCnt, logType, otherData)
 	return true
 end
 
+
 ---------------------------- msg --------------------------------
 -- 发送背包道具
 function sendBagList(human)
@@ -320,20 +339,71 @@ end
 
 -- 改变
 function sendChange(human, itemID, isAdd)
-	print("12131231进入下发逻辑")
+	--print("12131231进入下发逻辑")
 	local msgRet = Msg.gc.GC_ITEM_BAG_CHANGE
 	local itemCnt = human.db.bag[itemID] or 0
 	msgRet.itemID = itemID	
 	msgRet.itemCnt = itemCnt
 	msgRet.itemData[0] = 0
 	if isAdd == true then
-		print("下发为true")
+		--print("下发为true")
 		msgRet.itemData[0] = 1
 		Grid.makeItem(msgRet.itemData[1], itemID, itemCnt, nil,nil,nil, Grid.getOpflagAtBag(itemID))
 	end
 	Msg.send(msgRet, human.fd)
 end
 
+function sendListChange(human, tItemList)
+	local tAllList , tFlag = {}, {}
+	if tItemList[1] and tItemList[1][1] then
+		for _, v in ipairs(tItemList) do
+			if not tFlag[v[1]] then
+				tFlag[v[1]] = true
+				table.insert(tAllList, v[1])
+			end
+		end
+	else
+		for itemID, itemNum in pairs(tItemList) do
+			if not tFlag[itemID] then
+				tFlag[itemID] = true
+				table.insert(tAllList, itemID)
+			end
+		end
+	end
+	
+	if nil == _G.next(tAllList) then
+		return
+	end
+
+	local msgRet = Msg.gc.GC_ITEM_BAG_LIST_CHANGE
+	msgRet.tList[0] = 0
+	msgRet.bStart = 1
+	msgRet.bEnd = 0
+	local nLen, nAllLen, nSendLen = 0, 0, 0
+	
+	nAllLen = #tAllList
+	for _, v in ipairs(tAllList) do
+		nSendLen = nSendLen + 1
+		nLen = nLen + 1
+		local tData = msgRet.tList[nLen]
+		local nNowNum = getItemCnt(human, v)
+		Grid.makeItem(tData, v, nNowNum, nil,nil,nil, Grid.getOpflagAtBag(v))
+		if nLen >= 30 then
+			msgRet.tList[0] = nLen
+			Msg.send(msgRet, human.fd)
+			nLen = 0
+			msgRet.bStart = 0
+			msgRet.bEnd = nSendLen == nAllLen and 1 or 0
+		end
+	end
+	
+	if nLen > 0 then
+		msgRet.tList[0] = nLen
+		msgRet.bEnd = 1
+		Msg.send(msgRet, human.fd)
+	end
+end
+
 -- 滚动
 function sendRoll(human, itemID, itemCnt)
     

+ 21 - 12
script/module/bag/Grid.lua

@@ -361,7 +361,8 @@ function makeItemSuipian(net, itemConfig)
 	if itemConfig.subType ~= ItemDefine.ITEM_SUBTYPE_SUIPIAN and
 		itemConfig.subType ~= ItemDefine.ITEM_SUBTYPE_SUIPIAN_SKIN and
 		itemConfig.subType ~= ItemDefine.ITEM_SUBTYPE_SUIPIAN_TALISMAM and
-		itemConfig.subType ~= ItemDefine.ITEM_SUBTYPE_SUIPIAN_RELIC then
+		itemConfig.subType ~= ItemDefine.ITEM_SUBTYPE_SUIPIAN_RELIC and
+		itemConfig.subType ~= ItemDefine.ITEM_SUBTYPE_SUIPIAN_ELF then
 		return
 	end
 
@@ -390,7 +391,9 @@ function makeItemSuipian(net, itemConfig)
 				end
 			end
 		end
-	elseif itemConfig.subType == ItemDefine.ITEM_SUBTYPE_SUIPIAN_TALISMAM or itemConfig.subType == ItemDefine.ITEM_SUBTYPE_SUIPIAN_RELIC then
+	elseif itemConfig.subType == ItemDefine.ITEM_SUBTYPE_SUIPIAN_TALISMAM or
+			itemConfig.subType == ItemDefine.ITEM_SUBTYPE_SUIPIAN_RELIC or 
+			itemConfig.subType == ItemDefine.ITEM_SUBTYPE_SUIPIAN_ELF then
 		net.suipian[1].camp = 0
 		net.suipian[1].star = 0
 		net.suipian[1].grade = itemConfig.rare or 0
@@ -458,6 +461,11 @@ function getOpflagAtBag(id)
         flag = Util.setBit(flag, ItemDefine.ITEM_OP_FJIE)
     end
 
+	-- 能否兑换
+	if canDuiHuang(itemConfig) then
+		flag = Util.setBit(flag, ItemDefine.ITEM_OP_DUIHUAN)
+	end
+
 	return flag
 end
 
@@ -569,16 +577,7 @@ function canHeCheng(itemConfig)
 	local getWay = itemConfig.get and itemConfig.get[1]
 	if getWay == SuipianLogic.SUMMON_TYPE_TARGET or getWay == SuipianLogic.SUMMON_TYPE_DROP then	
 		local suipianType = itemConfig.get[2]
-		if suipianType == SuipianLogic.SUMMON_SUBTYPE_HERO then
-			return true
-		end
-		if suipianType == SuipianLogic.SUMMON_SUBTYPE_SKIN then
-			return true
-		end
-		if suipianType == SuipianLogic.SUMMON_SUBTYPE_TALISAM then
-			return true
-		end
-		if suipianType == SuipianLogic.SUMMON_SUBTYPE_RELIC then
+		if true == SuipianLogic.SuipianLogic_CanHeCheng(suipianType) then
 			return true
 		end
 	end
@@ -613,6 +612,16 @@ function canFJie(itemConfig)
     end
 end
 
+function canDuiHuang(itemConfig)
+	local nID = itemConfig.id
+	local getWay = itemConfig.get and itemConfig.get[1]
+	if getWay == SuipianLogic.SUMMON_TYPE_TARGET then	
+		local nDuiHuangType = itemConfig.get[2]
+		if true == SuipianLogic.SuipianLogic_CanDuiHuang(nDuiHuangType) then
+			return true
+		end
+	end
+end
 
 
 

+ 8 - 0
script/module/bag/Handler.lua

@@ -83,4 +83,12 @@ end
 
 function CG_ITEM_CHOSE_SKIN(huamn, msg)
 	HeroSkinLogic.BuySkinBySuiPian(huamn, msg.nSkinID, msg.nItemID)
+end
+
+function CG_DUIHUANG_QUERY(human, msg)
+	SuipianLogic.SuiPianLogic_DuiHuangQuery(human, msg.nID)
+end
+
+function CG_DUIHUANG_DO(human, msg)
+	SuipianLogic.SuiPianLogic_DuiHuangDo(human, msg.nID, msg.nNum)
 end

+ 4 - 1
script/module/bag/ItemDefine.lua

@@ -41,6 +41,8 @@ ITEM_SUBTYPE_TALISMAM = 4 			-- 秘宝
 ITEM_SUBTYPE_SUIPIAN_TALISMAM = 5 	-- 秘宝碎片
 ITEM_SUBTYPE_RELIC=6                -- 遗物
 ITEM_SUBTYPE_SUIPIAN_RELIC =7       -- 遗物碎片
+ITEM_SUBTYPE_ELF = 8	 			-- 精灵
+ITEM_SUBTYPE_SUIPIAN_ELF = 9        -- 精灵碎片
 
 -- 道具可操作类型
 ITEM_OP_USE = 1 				-- 使用
@@ -54,10 +56,11 @@ ITEM_OP_HECHENG  = 8            -- 合成
 ITEM_OP_EQUIP  = 9              -- 能否穿戴
 ITEM_OP_CZHU  = 10              -- 能否重铸
 ITEM_OP_FJIE  = 11              -- 能否分解
+ITEM_OP_DUIHUAN = 12			-- 能否兑换
 
 PAGE_LIST_COUNT = 30   			--游戏背包每次发送的数量
 BAG_ITEM_MAX_CNT = 2100000000 	-- 背包道具叠加上限
-BAG_ITEM_MAX_JINBI = 999999999999 -- 携带金币上限	
+BAG_ITEM_MAX_JINBI = 999999999999 -- 携带金币上限
 
 
 ITEM_JINBI_ID			        = 101       -- 金币

+ 1 - 1
script/module/bag/ItemLogic.lua

@@ -139,7 +139,7 @@ function cmd.boxRand(data, human, list)
     end
 
 	data.left = 0
-	BagLogic.addMomentItemList(human, "useBox")
+	BagLogic.addMomentItemList(human, "useBox", true)
 end
 
 -- 固定箱子

+ 21 - 0
script/module/bag/Proto.lua

@@ -125,6 +125,13 @@ GC_ITEM_BAG_CHANGE = {
 	{"itemData",   2,   ItemData},  -- 只有新增的时候长度为1 其他情况长度为0
 }
 
+-- 批量同步道具背包改变
+GC_ITEM_BAG_LIST_CHANGE = {
+	{"bStart",	 1,		"byte"},	-- 1开始 0
+	{"bEnd",	 1,		"byte"},	-- 1结束 0
+	{"tList",	  30,	ItemData},
+}
+
 -- 背包道具出售
 CG_BAG_ITEM_SELL = {
 	{"id",                1,      "int"},
@@ -315,3 +322,17 @@ CG_ITEM_CHOSE_SKIN = {
 	{"nSkinID",	1,		"int"},		-- 选择的皮肤ID
 	{"nItemID",	1,		"int"},		-- 物品ID
 }
+
+CG_DUIHUANG_QUERY = {
+	{"nID",		1,		"int"},		-- 物品ID
+}
+
+GC_DUIHUANG_QUERY = {
+	{"nUseNum",		1,		"int"},		-- 消耗物品数量
+	{"ItemData",	1,		ItemData},
+}
+
+CG_DUIHUANG_DO = {
+	{"nID",		1,		"int"},		-- 物品ID
+	{"nNum",	1,		"int"},		-- 兑换数量
+}

+ 83 - 7
script/module/bag/SuipianLogic.lua

@@ -19,11 +19,30 @@ SUMMON_TYPE_DROP      = 2 -- 随机掉落表兑换
 SUMMON_TYPE_HERO_SP   = 3 -- 英雄条件兑换
 SUMMON_TYPE_SHENQI_SP = 4 -- 神器条件兑换
 
+SUMMON_SUBTYPE_MIN = 1 
 SUMMON_SUBTYPE_HERO = 1 -- 英雄
 SUMMON_SUBTYPE_EQUIP = 2 -- 装备
 SUMMON_SUBTYPE_SKIN = 3  -- 皮肤
 SUMMON_SUBTYPE_TALISAM = 4 --秘宝
 SUMMON_SUBTYPE_RELIC = 5  --遗物
+SUMMON_SUBTYPE_ELF = 6  -- 精灵
+
+SUMMON_SUBTYPE_MAX = 6
+
+SUMMON_HECHENG_TYPE_GOOD = 11 --可合成物品
+
+function SuipianLogic_CanHeCheng(nID)
+	if nID == SUMMON_SUBTYPE_HERO or nID == SUMMON_SUBTYPE_SKIN  or SUMMON_SUBTYPE_TALISAM == nID 
+		or SUMMON_SUBTYPE_RELIC == nID or SUMMON_SUBTYPE_ELF == nID then
+			return true
+	end
+	
+	return false
+end
+
+function SuipianLogic_CanDuiHuang(nID)
+	return SUMMON_HECHENG_TYPE_GOOD == nID
+end
 
 -- 查询
 function query(human, itemID)
@@ -65,11 +84,7 @@ function summon(human, itemID, itemUseCnt)
 		return
 	end
 
-	if itemConfig.get[2] ~= SUMMON_SUBTYPE_HERO 
-	and itemConfig.get[2] ~= SUMMON_SUBTYPE_EQUIP
-	and itemConfig.get[2] ~= SUMMON_SUBTYPE_SKIN
-	and itemConfig.get[2] ~= SUMMON_SUBTYPE_TALISAM 
-	and itemConfig.get[2] ~= SUMMON_SUBTYPE_RELIC then
+	if itemConfig.get[2] < SUMMON_SUBTYPE_MIN or SUMMON_SUBTYPE_MAX < itemConfig.get[2] then
 		return
 	end
 	
@@ -852,13 +867,16 @@ end
 
 
 function CG_SUIPIAN_SYNTHESIS(human, synthesisType)
-	if not synthesisType or synthesisType < SUMMON_SUBTYPE_HERO  or synthesisType > SUMMON_SUBTYPE_RELIC then
+	if not synthesisType or synthesisType < SUMMON_SUBTYPE_HERO  or synthesisType > SUMMON_SUBTYPE_ELF then
 		print("[CG_SUIPIAN_SYNTHESIS] 合成类型错误 synthesisType = "..synthesisType)
 		return
 	end
 
 	--目前只有三种碎片能合成
-	if synthesisType ~= SUMMON_SUBTYPE_HERO and  synthesisType ~= SUMMON_SUBTYPE_TALISAM and synthesisType ~= SUMMON_SUBTYPE_RELIC then
+	if synthesisType ~= SUMMON_SUBTYPE_HERO and 
+		synthesisType ~= SUMMON_SUBTYPE_TALISAM and
+		synthesisType ~= SUMMON_SUBTYPE_RELIC and 
+		synthesisType ~= SUMMON_SUBTYPE_ELF then
 		print("[CG_SUIPIAN_SYNTHESIS] 合成类型错误 synthesisType = "..synthesisType)
 		return
 	end
@@ -892,6 +910,8 @@ function CG_SUIPIAN_SYNTHESIS(human, synthesisType)
 		targetSubType = ItemDefine.ITEM_SUBTYPE_SUIPIAN_TALISMAM
 	elseif synthesisType == SUMMON_SUBTYPE_RELIC then
 		targetSubType = ItemDefine.ITEM_SUBTYPE_SUIPIAN_RELIC
+	elseif synthesisType == SUMMON_SUBTYPE_ELF then
+		targetSubType = ItemDefine.ITEM_SUBTYPE_SUIPIAN_ELF
 	end
 
 	for itemID,itemCnt in pairs(human.db.bag) do
@@ -917,3 +937,59 @@ function CG_SUIPIAN_SYNTHESIS(human, synthesisType)
 	msgRet.status = status
 	Msg.send(msgRet, human.fd)
 end
+
+
+function SuiPianLogic_DuiHuangQuery(human, nID)
+	local itemConfig = ItemDefine.getConfig(nID)
+	if not itemConfig then
+		return
+	end
+
+	local tGetInfo = itemConfig.get
+	if nil == _G.next(tGetInfo) then
+		return
+	end
+
+	if tGetInfo[1] ~= SUMMON_TYPE_TARGET or tGetInfo[2] ~= SUMMON_HECHENG_TYPE_GOOD  then
+		return
+	end
+
+	local tTargetID = tGetInfo[3]
+	local nUseNum = itemConfig.nUseNum
+	if 0 >= nUseNum then
+		return
+	end
+
+	local tMsgData = Msg.gc.GC_DUIHUANG_QUERY
+	tMsgData.nUseNum = nUseNum
+	Grid.makeItem(tMsgData.ItemData, tTargetID, itemConfig.nGetNum)
+
+	Msg.send(tMsgData, human.fd)
+end
+
+function SuiPianLogic_DuiHuangDo(human, nID, nTargetNum)
+	local itemConfig = ItemDefine.getConfig(nID)
+	if not itemConfig then
+		return
+	end
+
+	local tGetInfo = itemConfig.get
+	if nil == _G.next(tGetInfo) then
+		return
+	end
+
+	if tGetInfo[1] ~= SUMMON_TYPE_TARGET or tGetInfo[2] ~= SUMMON_HECHENG_TYPE_GOOD  then
+		return
+	end
+
+	local nUseNum = nTargetNum * itemConfig.nUseNum
+	if 0 >= nUseNum or nUseNum > BagLogic.getItemCnt(human, nID) then
+		return
+	end
+
+	local nAddNum = nTargetNum * itemConfig.nGetNum
+
+	-- print("[SuiPianLogic_DuiHuangDo]")
+	BagLogic.delItem(human, nID, nUseNum, "item_hecheng")
+	BagLogic.addItemList(human, {{tGetInfo[3], nAddNum}}, "item_hecheng")
+end

+ 47 - 0
script/module/battleDataManager/BattleDataCS.lua

@@ -0,0 +1,47 @@
+-- 用于跨服通知普通服上传玩家战斗数据及收到数据后的处理
+
+local InnerMsg = require("core.InnerMsg")
+local MiddleManager = require("middle.MiddleManager")
+local AreaBattleCS = require("areaBattle.AreaBattleCS")
+
+
+AREABTTLE_TAG = 1
+
+
+
+
+
+function NotifyNormalSrv(fd, playerUuid, moduleTag, combatType, extraArgs)
+    local msgData = InnerMsg.wl.WL_COMBAT_DATA
+    msgData.playerUuid = playerUuid
+    msgData.moduleTag = moduleTag
+    msgData.combatType = combatType
+    msgData.extraArgs = extraArgs
+    InnerMsg.sendMsg(fd, msgData)
+end
+
+-- 其他模块调用,用于请求所需战斗数据
+function GetPlayerCombatData(serverId, playerUuid, moduleTag, combatType, extraArgs)
+    if not serverId or not playerUuid or not moduleTag then
+        return
+    end
+
+    -- 后续再扩展
+    if moduleTag ~= AREABTTLE_TAG then
+        return
+    end
+
+    local fd = MiddleManager.getFDBySvrIndex(serverId)
+    if not fd then
+        return
+    end
+
+    NotifyNormalSrv(fd, playerUuid, moduleTag, combatType, extraArgs)
+end
+
+-- 收到普通服上传的战斗数据
+function BattleDataHandleManager(fd, msg)
+    if msg.moduleTag == AREABTTLE_TAG then
+        AreaBattleCS.BattleDataHanle(msg)
+    end
+end

+ 68 - 0
script/module/battleDataManager/BattleDataNS.lua

@@ -0,0 +1,68 @@
+-- 用于普通服收到跨服通知上传战斗数据的处理
+
+local InnerMsg = require("core.InnerMsg")
+local CombatDefine = require("combat.CombatDefine")
+local CombatLogic = require("combat.CombatLogic")
+local MiddleDefine = require("middle.MiddleDefine")
+local CombatPosLogic = require("combat.CombatPosLogic")
+
+
+
+
+function CreateBattleData(fd, msg)
+    local tMsgData = InnerMsg.lw.LW_COMBAT_DATA
+    tMsgData.moduleTag = msg.moduleTag
+    tMsgData.extraArgs = msg.extraArgs
+
+    local playerUuid = msg.playerUuid
+    local nCombatType = msg.nCombatType or CombatDefine.COMBAT_TYPE1
+    local fakeHuman = CombatLogic.createCombatFakeHuman(playerUuid)
+
+	if not fakeHuman then
+        tMsgData.errCode = MiddleDefine.MIDDLE_GET_COMBAT_ERR_ONE
+        print("[BattleDataNS] 没有获取到对应玩家")
+        InnerMsg.sendMsg(0, tMsgData)
+        return
+    end
+
+	-- local combatHero = CombatPosLogic.getCombatHeros(fakeHuman, CombatDefine.COMBAT_TYPE1, nil, true)
+    local combatHero = CombatPosLogic.getCombatHeros(fakeHuman, nCombatType, nil, true)
+	if not combatHero or not next(combatHero) then
+        print("[BattleDataNS] 没有获取到对应玩家的英雄列表, 取默认战斗列表")
+        combatHero = CombatPosLogic.getCombatHeros(fakeHuman, CombatDefine.COMBAT_TYPE1, nil, true)
+        if not combatHero or not next(combatHero) then
+            print("[BattleDataNS] 取默认战斗列表还是没有获取到英雄列表")
+            tMsgData.errCode = MiddleDefine.MIDDLE_GET_COMBAT_ERR_TWO
+            InnerMsg.sendMsg(0, tMsgData)
+            return
+        end
+	end
+
+    local moduleFn = CombatLogic.getModule(msg.combatType)
+    if not moduleFn or not moduleFn.getCombatObjList then
+        print("[BattleDataNS] 未实现的获取战斗对象函数")
+        tMsgData.errCode = MiddleDefine.MIDDLE_GET_COMBAT_ERR_THREE
+        InnerMsg.sendMsg(0, tMsgData)
+        return
+    else
+        local args  = {
+            [1] = playerUuid
+        }
+        local objList, helpList, rolebase, formation,jiban, elfList = moduleFn.getCombatObjList(nil, CombatDefine.DEFEND_SIDE, args, msg.combatType)
+        if objList then
+            tMsgData.errCode = MiddleDefine.MIDDLE_GET_COMBAT_OK
+            tMsgData.objList = objList
+            tMsgData.helpList = helpList
+            tMsgData.roleBase = rolebase
+            tMsgData.formation = formation
+            tMsgData.jiBan = jiban
+            tMsgData.elfList = elfList or {}
+            InnerMsg.sendMsg(0, tMsgData)
+        else
+            print("[BattleDataNS] 获取对战英雄列表失败")
+            tMsgData.errCode = MiddleDefine.MIDDLE_GET_COMBAT_ERR_FOUR
+            InnerMsg.sendMsg(0, tMsgData)
+            return
+        end
+    end
+end

+ 6 - 0
script/module/billboard/BillboardLogic.lua

@@ -148,4 +148,10 @@ function isDot(human)
 		end
 	end
     return false
+end
+
+
+function GetRankList(boardType)
+	local board = BillboardDB.getBoard(boardType)
+	return board and board.rank2data
 end

+ 1 - 1
script/module/chat/Gm.lua

@@ -2140,7 +2140,7 @@ function d3.getAll(human)
 		end
 	end
 	for _, id in ipairs(allHeroIds) do
-		local val = string.format("%d %d %d %d", id, 1, 400, 15)
+		local val = string.format("%d %d %d %d", id, 1, 1000, 20)
 		d3.heroadd(human, val)
 	end
 	local items = {

+ 13 - 0
script/module/chengjiu/ChengjiuLogic.lua

@@ -294,6 +294,10 @@ function getReward(human,taskID)
     ObjHuman.sendAttr(human, RoleDefine.ZHANDOULI)
     GuideLogic.setDoSpecialGuide(human, GuideLogic.SKIPTYPE_JUMP_JIEFENG_BAOJU)
     RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_2001)
+
+    if taskID == 406 then
+        RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_2031)
+    end
 end
 
 -- 回调
@@ -323,6 +327,7 @@ function onCallback(human,taskType,cnt)
             RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_2001)
             RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_2002)
             RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_2004)
+            RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_2031)
             
             local msgRet = Msg.gc.GC_CHENGJIU_SET
             msgRet.taskID = k
@@ -488,4 +493,12 @@ end
 --GM, 重置所有数据
 function GM_ClearAllData(human)
     human.db.chengjiu = {}
+end
+
+
+function GetTaskState(human, taskId)
+    if not human.db.chengjiu or not human.db.chengjiu.task then
+        return CJ_TASK_STATE_0
+    end
+    return human.db.chengjiu.task[taskId] or CJ_TASK_STATE_0
 end

+ 46 - 6
script/module/combat/BeSkill.lua

@@ -16,6 +16,7 @@ local ProjectLogic = require("platform.ProjectLogic")
 local HeroDefine = require("hero.HeroDefine")
 local WinnerRelicLogic = require("winnerRelic.WinnerRelicLogic")
 local TargetMode = require("combat.TargetMode")
+local HeroExclusiveWeapon = require("hero.HeroExclusiveWeapon")
 
 
 local tbFuwenSkillGroupID = {}
@@ -146,19 +147,15 @@ function setBeSkill(obj, config, skinConf, monsterOutConfig)
 	if obj.relic and nil ~= _G.next(obj.relic) then
 		local nRelicID = obj.relic.relicID
 		local star = obj.relic.star
-		-- print("当前获取到的星级",star)
 		local nSkillID = WinnerRelicLogic.WinnerRelic_GetSkillID(nRelicID, star)
-		print("[setBeSkill] nSkillID = "..nSkillID)
 		if 0 < nSkillID then
 			setBeSkillID(obj, nSkillID, 0, 1)
 			
 			local tSkilConfig = SkillExcel and SkillExcel[nSkillID]
-			-- print("当前获取到的skillid2222222222",tSkilConfig.id)
 			if tSkilConfig and tSkilConfig.otherArgs and tSkilConfig.otherArgs.skillList then
 				for k,v in ipairs(tSkilConfig.otherArgs.skillList) do
 					local config = SkillExcel[v]
 					if config and config.id then
-						-- print("當前设置的skillid",config.id)
 						setBeSkillID(obj, config.id, 0, 1)
 					end
 				end
@@ -252,6 +249,7 @@ BESKILL_TYPE68 = 68 --血族英雄特殊处理
 BESKILL_TYPE69 = 69 --血族英雄特殊处理
 BESKILL_TYPE70 = 70 --增加的属性激活就生效(计入面板属性)并且概率连击
 BESKILL_TYPE71 = 71	--回合开始 在其他buff添加结束
+BESKILL_TYPE72 = 72	-- 不施放技能,只用来做其他效果的判断条件
 
 
 NO_CHECK_FANJI_LIST = {
@@ -281,6 +279,7 @@ NO_CHECK_COMBO_LIST = {
 	[BESKILL_TYPE46] = 1,
     [BESKILL_TYPE37] = 1,
 	[BESKILL_TYPE38] = 1,
+	[BESKILL_TYPE43] = 1,
 }
 
 local function checkLimit(data)
@@ -562,7 +561,7 @@ local function use(attacker,targets,data,newFrame, packBuff, hitObj)
 end
 
 function onHit(attacker,targets,skillID)
-	if attacker.isPet then
+	if attacker.isPet or attacker.isElf then
 		return
 	end
 
@@ -1361,7 +1360,7 @@ function onRoundBegin(round)
 end
 
 function beforeFanji(obj, hitObj, isEnd)
-	if not obj or obj.isPet then
+	if not obj or obj.isPet or obj.isElf then
 		return 
 	end
 
@@ -1638,8 +1637,12 @@ function doCalcHero(obj, attrs, skinSkillID, heroConf)
 	if skinSkillConf then
 		beSkillIDs = skinSkillConf.beSkillList
 	end
+
+	local weapSkillList = HeroExclusiveWeapon.GetweaponEffectIdList(obj)
+
 	for _, skillID in ipairs(beSkillIDs) do
 		--local skillConfig = SkillExcel[skillID]
+		skillID = weapSkillList and weapSkillList[skillID] or skillID
 		local skillConfig = Skill.GetSkillConfig(skillID)
 		if skillConfig.beSkillType == BESKILL_TYPE24 and 
 			((not obj) or (obj.quality >= skillConfig.need)) then
@@ -1723,9 +1726,33 @@ function getOutAtkRate(attacker, defender)
           end
        end 
     end
+
     return outAtkRate
 end
 
+function getOutAtkRate2(attacker, skillConfig)
+	local outAtkRate = 0
+	for _, v in ipairs(attacker.beSkillList[BESKILL_TYPE72] or {})  do
+		local config = Skill.GetSkillConfig(v[1])
+		if config.cmd == "addHurtRateByRand" then
+			local addHurtRate = 0
+			for _, skillInfo in ipairs(config.beSkillArgs[2]) do
+				if table.find(skillInfo[1], skillConfig.id) then
+					addHurtRate = skillInfo[2]
+					break
+				end
+			end
+
+			local randVal = math.random(0, 10000)
+			if randVal <= config.beSkillArgs[1] then
+				outAtkRate = outAtkRate + addHurtRate
+			end
+		end
+	end
+	return outAtkRate
+end
+
+
 
 function getExtraHurtRate(attacker,defender,skillConfig)
 	if not attacker or attacker.isPet then
@@ -2241,4 +2268,17 @@ function getStatusPojia(attacker, defender)
       end
    end
    return poJia
+end
+
+-- 是否不会被反击
+function isNoFanji(obj)
+	if obj.beSkillList[BESKILL_TYPE72] then
+		for _, v in ipairs(obj.beSkillList[BESKILL_TYPE72]) do
+			local skillConfig = Skill.GetSkillConfig(v[1])
+			if skillConfig.cmd == "noFanji" then
+				return true
+			end
+        end
+	end
+	return false
 end

+ 223 - 35
script/module/combat/CombatBuff.lua

@@ -34,7 +34,8 @@ end
 
 --和血量相关的作用
 local function isHpCmd(cmd)
-	if cmd == "hp" or cmd == "hurt" or cmd == "hurt1" or cmd == "liuxue" or cmd == "liuxue2" or cmd == "zhongdu" or cmd == "ranshao" or cmd == "ranshao1" or cmd == "huiheYinji" then
+	if cmd == "hp" or cmd == "hurt" or cmd == "hurt1" or cmd == "liuxue" or cmd == "liuxue2" or cmd == "liuxue3"
+		or cmd == "zhongdu" or cmd == "ranshao" or cmd == "ranshao1" or cmd == "huiheYinji" then
 		return true
 	end
 	return false
@@ -42,7 +43,9 @@ end
 
 --控制类buff
 function isControlCmd(cmd)
-	if  cmd == "xuanyun" or cmd == "shihua" or cmd == "bingdong" or cmd == "chanrao" or cmd == "xuanyun2" or cmd == "chenshui" then
+	if  cmd == "xuanyun" or cmd == "shihua" or cmd == "bingdong"
+		or cmd == "chanrao" or cmd == "xuanyun2" or cmd == "chenshui"
+		or cmd == "donghe" or cmd == "gandian" then
 		return true
 	end
 end
@@ -55,7 +58,8 @@ function isStop(obj)
 	local bufferCmd = obj.bufferCmd
 	local ret
 	if bufferCmd["xuanyun"] or bufferCmd["shihua"] or bufferCmd["bingdong"]
-		or bufferCmd["chanrao"] or bufferCmd["xuanyun2"] or bufferCmd["chenshui"] then
+		or bufferCmd["chanrao"] or bufferCmd["xuanyun2"] or bufferCmd["chenshui"]
+		or bufferCmd["donghe"] or bufferCmd["gandian"] then
 
 		ret = 1
 	elseif bufferCmd["xuanyun"] or bufferCmd["xuanyun2"] then
@@ -75,7 +79,7 @@ function IsJustHaveChanraoBuff(obj)
 		return false
 	end
 	
-	if bufferCmd["xuanyun"] or bufferCmd["shihua"] or bufferCmd["bingdong"] or bufferCmd["xuanyun2"] then
+	if bufferCmd["xuanyun"] or bufferCmd["shihua"] or bufferCmd["bingdong"] or bufferCmd["xuanyun2"] or bufferCmd["donghe"] or bufferCmd["gandian"] then
 		return false
 	end
 
@@ -203,6 +207,7 @@ CMD2KEY = {
 	["ranshao1"] = RoleDefine.STATUS_MIANYI_RATE5,
 	["liuxue"] = RoleDefine.STATUS_MIANYI_RATE6,
 	["liuxue2"] = RoleDefine.STATUS_MIANYI_RATE6,
+	["liuxue3"] = RoleDefine.STATUS_MIANYI_RATE6,
 	["zhongdu"] = RoleDefine.STATUS_MIANYI_RATE7,
     ["hunluan"] = RoleDefine.STATUS_MIANYI_RATE9,
 	["xuanyun2"] = RoleDefine.STATUS_MIANYI_RATE1,
@@ -227,6 +232,14 @@ function isMianyi(obj,cmd)
     end
 end
 
+-- 特殊的控制buff, 不受控率属性和抗控属性影响
+local sp_ctr_buff_list = {
+	["xuanyun2"] = true,
+	["donghe"] = true,
+	["gandian"] = true,
+}
+
+
 local function isMiankong(obj, cmd, attacker, skillKongRate)
     if not isControlCmd(cmd) then return end
     if not attacker then return end
@@ -246,7 +259,11 @@ local function isMiankong(obj, cmd, attacker, skillKongRate)
     kongRate = kongRate < 0 and 0 or kongRate
 
 
-	if cmd == "xuanyun2" then
+	-- if cmd == "xuanyun2" or cmd == "donghe" then
+	-- 	kongRate = skillKongRate
+	-- end
+
+	if sp_ctr_buff_list[cmd] then
 		kongRate = skillKongRate
 	end
 
@@ -321,6 +338,30 @@ local function isPos(obj,posList)
 	end
 end
 
+function isLianjie1(obj)
+	if obj.bufferCmd["lianjie1"] then
+		return true
+	end
+
+	return false
+end
+
+function CombatBuff_handleLianjie(v, attacker)
+	local LianJieBufferInd = v.bufferCmd["lianjie1"] and v.bufferCmd["lianjie1"][1]
+	local LianJieBBuffer = v.buffer[LianJieBufferInd]
+	if LianJieBBuffer then
+		local conf = GetBuffConfig(LianJieBBuffer.id)
+		handler[conf.cmd](v, LianJieBBuffer, conf, attacker)
+	end
+end
+
+local function isLianjie2(obj)
+	if obj.bufferCmd["lianjie2"] then
+		return true
+	end
+	
+	return false
+end
 
 function getBuffer(obj)
 	return obj.buffer
@@ -348,7 +389,9 @@ function onBufferChange(obj)
         conf.cmd == "jiansu" or 
         conf.cmd == "defRate" or 
         conf.cmd == "defRate2" or 
-        conf.cmd == "attrQusan" then
+        conf.cmd == "attrQusan" or 
+		conf.cmd == "qianxing" or 
+		conf.cmd == "gandian" then
 
 			if type(buffer.arg) == "table" then
 				for j = 1,#buffer.arg do
@@ -430,7 +473,7 @@ function onBufferChange(obj)
 		end
 		bufferCmd[conf.cmd] = bufferCmd[conf.cmd] or {}
 		bufferCmd[conf.cmd][#bufferCmd[conf.cmd] + 1] = i
-	end	
+	end
 	CombatObj.calcAttr(obj)
 	for pos in pairs(changeList) do
 		CombatObj.calcAttr(CombatImpl.objList[pos])
@@ -884,10 +927,12 @@ function addBuffer(attackPos,obj, id, skillID,arg,parentConf)
 	end
 
 	local attacker
-	if attackPos > CombatDefine.COMBAT_HERO_ALL_CNT then
-		attacker = CombatImpl.helpList[attackPos]
-	else
+	if attackPos <= CombatDefine.COMBAT_HERO_ALL_CNT then
 		attacker = CombatImpl.objList[attackPos]
+	elseif attackPos > CombatDefine.COMBAT_HERO_ALL_CNT and attackPos < CombatDefine.COMBAT_HERO_ALL_CNT + CombatDefine.COMBAT_HELP_ALL_CNT then
+		attacker = CombatImpl.helpList[attackPos]
+	elseif attackPos >= CombatDefine.ELF_MIN_POS then
+		attacker = CombatImpl.elfList[attackPos]
 	end
 	if arg then
 		buffer.arg = arg
@@ -1104,6 +1149,16 @@ function onHit(attacker, skillTargets, skillConfig, cmdTargets, otherArgs)
                 end
             end
         end
+
+		if true == isLianjie1(v) then
+			CombatBuff_handleLianjie(v, attacker)
+			-- local LianJieBufferInd = v.bufferCmd["lianjie1"] and v.bufferCmd["lianjie1"][1]
+            -- local LianJieBBuffer = v.buffer[LianJieBufferInd]
+			-- if LianJieBBuffer then
+			-- 	local conf = GetBuffConfig(LianJieBBuffer.id)
+			-- 	handler[conf.cmd](v, LianJieBBuffer, conf, attacker)
+			-- end
+		end
     end
 
     local buffers = getSkillBuffers(skillConfig)
@@ -1436,6 +1491,7 @@ function onRoundEnd(attacker,isRoundEnd)
 					obj.delayAddBuffer = nil
 				end
 			end
+			
 			delayEnd()
 		end
 	end
@@ -1487,6 +1543,7 @@ function getExtraHurtRate(attacker,target,skillConfig)
 		biaoshiCntLimit = skillConfig.otherArgs.biaoshiHurtRate[1]
 	end
 
+	local bHaveQianXing  = false  -- 是否有潜行
 	for j = target.buffer[0], 1, -1 do
 		local obj = target
 		local buffer = obj.buffer[j]
@@ -1505,9 +1562,12 @@ function getExtraHurtRate(attacker,target,skillConfig)
 			biaoshiCnt = biaoshiCnt + 1
 		elseif conf.cmd == "chenshui" then
 			chenshuiHurtRate = chenshuiHurtRate + 3000
+		elseif conf.cmd == "qianxing" then
+			bHaveQianXing = true
 		end
 	end
 
+	local bHaveTrueVision, nTrueVisionBuffID = false, 0	-- 是否有真视
 	--攻击者
 	for j = attacker.buffer[0], 1, -1 do
 		local obj = attacker
@@ -1533,9 +1593,20 @@ function getExtraHurtRate(attacker,target,skillConfig)
 				zhanyiHurtRate = percent * args[2]
 				break
 			end
+		elseif conf.cmd == "truevision" then
+			bHaveTrueVision = true
+			nTrueVisionBuffID = buffer.id
 		end
 	end
 
+	local TrueVisionRate = 0
+	if bHaveTrueVision and bHaveQianXing then
+		local conf = GetBuffConfig(nTrueVisionBuffID)
+		TrueVisionRate = TrueVisionRate + conf.args[1]
+		delBufferByCmd(target,"qianxing",1)
+		-- print("[CombatBuff_getExtraHurtRate] 真视对潜行增伤 并删除对应的潜行buffer TrueVisionRate = "..TrueVisionRate
+		-- 	.." buffid = "..nTrueVisionBuffID.." args[1] = "..conf.args[1])
+	end
 
 	guanxinzheHurtRate = guanxinzheHurtRate > 30000 and 30000 or guanxinzheHurtRate --300%限制
 	if biaoshiCntLimit and biaoshiCnt >= biaoshiCntLimit then
@@ -1543,7 +1614,7 @@ function getExtraHurtRate(attacker,target,skillConfig)
 	end
 
 	local extraHurtRate = baojiHurtRate + guanxinzheHurtRate + huiheHurtRate + shandianHurtRate
-	+ attackerHurtRat + biaoshiHurtRate + moweiHurtRate + zhanyiHurtRate + chenshuiHurtRate
+	+ attackerHurtRat + biaoshiHurtRate + moweiHurtRate + zhanyiHurtRate + chenshuiHurtRate + TrueVisionRate
 	return extraHurtRate
 end
 
@@ -1585,10 +1656,12 @@ local function chixuHurtDel2(target,buffer)
 	local conf = GetBuffConfig(buffer.id)
 	local attackPos = buffer.attackPos
 	local attacker
-	if attackPos > CombatDefine.COMBAT_HERO_ALL_CNT then
-		attacker = CombatImpl.helpList[attackPos]
-	else
+	if attackPos <= CombatDefine.COMBAT_HERO_ALL_CNT then
 		attacker = CombatImpl.objList[attackPos]
+	elseif attackPos > CombatDefine.COMBAT_HERO_ALL_CNT and attackPos < CombatDefine.COMBAT_HERO_ALL_CNT + CombatDefine.COMBAT_HELP_ALL_CNT then
+		attacker = CombatImpl.helpList[attackPos]
+	elseif attackPos >= CombatDefine.ELF_MIN_POS then
+		attacker = CombatImpl.elfList[attackPos]
 	end
 	local isAddHp = conf.cmd == "hp"
 	buffer.arg = CombatCalc.calcBufferHp(attacker,target,id,isAddHp)
@@ -1819,6 +1892,83 @@ function handler.zuzhou(target,buffer,conf)
     BeSkill.handlerBuff(attacker, target, hurt, conf.cmd)
 end
 
+function handler.lianjie1(target, buffer1, conf1, attacker)
+	if not attacker then
+		return
+	end
+
+	local nHurt = CombatObj.getValue(attacker, RoleDefine.HURT_COMBAT_NOW)
+	if 0 >= nHurt or not target then
+		print("[handler.lianjie1] 不正确的目标和伤害值")
+		return
+	end
+
+	if not target.bufferCmd or not target.bufferCmd["lianjie1"] then
+		print("[handler.lianjie1] 不存在对应buff")
+		return
+	end
+
+	local nTargetPos, nTargetSide = target.pos, target.side
+	print("[handler.lianjie1] 回合结束进行处理 nTargetPos =  "..nTargetPos.." nTargetSide = "..nTargetSide.." id = "..target.id)
+	for i = #target.bufferCmd["lianjie1"],1,-1 do
+		local ind = target.bufferCmd["lianjie1"][i]
+		local buffer = target.buffer[ind]
+		-- 自己身上有链接
+		local conf = GetBuffConfig(buffer.id)
+		local arg = conf.args[1]
+		local nDelHurt = nHurt * arg / 10000
+		print("[handler.lianjie1] 计算出来的值 nDelHurt =  "..nDelHurt.." arg = "..arg.." nHurt = "..nHurt)
+		local nGetSide = nTargetSide == CombatDefine.ATTACK_SIDE and CombatDefine.DEFEND_SIDE or CombatDefine.ATTACK_SIDE 
+		for _,pos in ipairs(CombatDefine.SIDE2POS[nGetSide]) do
+			local objM = CombatImpl.objList[pos]
+			if objM and objM.hp > 0 and isLianjie2(objM) then
+				local bHave = false
+				for j = #objM.bufferCmd["lianjie2"], 1, -1 do
+					local index = objM.bufferCmd["lianjie2"][j]
+					local tBuffData = objM.buffer[index]
+					if tBuffData and tBuffData.attackPos == nTargetPos then
+						bHave = true
+						break
+					end
+				end
+
+				if bHave == true then
+					print("[handler.lianjie1] 对目标英雄 进行扣血操作 id = "..target.id.." 目标英雄ID = "..objM.id .." nDelHurt = "..nDelHurt)
+					local d = CombatObj.updateHp(objM, -nDelHurt, nil, true, objM.pos,CombatObj.BUFFER_HP_TYPE)
+					CombatImpl.setExtraHit(objM, d)
+          			CombatObj.onHpCB(objM, d, objM.pos)
+				end
+			end
+		end
+	end
+end
+
+function handler.lianjie3(obj, buffer1, conf1, nAddNum)
+	if not obj.bufferCmd or not obj.bufferCmd["lianjie3"] or not nAddNum then
+		return
+	end
+
+	if 0 >= nAddNum then
+		return
+	end
+
+	for i = #obj.bufferCmd["lianjie3"], 1, -1 do
+		local ind = obj.bufferCmd["lianjie3"][i]
+		local buffer = obj.buffer[ind]
+		local nAttackPos = buffer.attackPos
+		local conf = GetBuffConfig(buffer.id)
+		local arg = conf.args[1]
+		local nSum = nAddNum * arg / 10000
+		local tAttacker = CombatImpl.objList[nAttackPos]
+		if tAttacker and tAttacker.hp > 0 then
+			-- print("[handler.lianjie3] 进行加血操作 nAddNum = "..nAddNum.." nSum  = "..nSum.." arg = "..arg)
+			local d = CombatObj.updateHp(tAttacker, nSum, nil, true, tAttacker.pos,CombatObj.BUFFER_HP_TYPE)
+			CombatImpl.setExtraHit(tAttacker, d)
+			CombatObj.onHpCB(tAttacker, d, tAttacker.pos)
+		end
+	end
+end
+
 function yinbaoZuzhou(obj, skillTargets, skillConfig)
     local newFrame = nil
 	for k,v in ipairs(skillTargets) do
@@ -1869,6 +2019,30 @@ function handlerEx.yinJi(target, buffer, conf)
 end
 
 
+
+handle2 = {}
+function handle2.liuxue3(target, buffer)
+	local hurt = chixuHurtDel2(target,buffer)
+	local d = CombatObj.updateHp(target, -hurt, nil, nil, buffer.attackPos,CombatObj.BUFFER_HP_TYPE)
+	buffer.attrs[RoleDefine.HP_COMBAT] = -hurt
+	onExtraCombatRecord(buffer.attackPos,hurt,"liuxue")
+end
+
+
+
+-- 有些buff, 在释放技能后会触发效果
+function BuffHandleAfterSkill(obj)
+	local res, _, idx = isStatus(obj, {"liuxue3"})
+	if res then
+		local buffer = obj.buffer[idx]
+		handle2.liuxue3(obj, buffer)
+		CombatImpl.addFrameBuffer(obj,buffer,CombatDefine.BUFFER_OP_HOLD)
+	end
+
+end
+
+
+
 function qingsuan(target)
 	if target.hp <= 0 then
 		return 0
@@ -1880,7 +2054,8 @@ function qingsuan(target)
 		--local conf = BufferExcel.buffer[buffer.id]
 		local conf = GetBuffConfig(buffer.id)
 		local cmd = conf.cmd
-		if cmd == "ranshao" or cmd == "ranshao1" or cmd == "liuxue"or cmd == "liuxue2" or cmd == "zhongdu" or cmd == "hurt" or cmd == "hurt1" then
+		if cmd == "ranshao" or cmd == "ranshao1" or cmd == "liuxue"or cmd == "liuxue2" or cmd == "liuxue3"
+			or cmd == "zhongdu" or cmd == "hurt" or cmd == "hurt1" then
 			round = 1
 			if buffer.round and buffer.round > 0 then
 				round = buffer.round
@@ -2090,27 +2265,36 @@ function qusanAddBuff(attacker, targets, bufferID)
     end		
 end
 
-function beforeUpdateHp(obj,sum)
-		local isStatus,cmd,ind = isStatus(obj,{"miansi","waitMiansi"})
-		if not isStatus then
-			return
-		end
-		--免死逻辑
-		if cmd == "miansi" then
-			return true
+function beforeUpdateHp(obj,sum, nAddNum, nDelHP)
+	local isLianjie, Lianjie2Cmd, index = isStatus(obj,{"lianjie3"})
+	if isLianjie then
+		local buffer = obj.buffer[index]
+		local conf = GetBuffConfig(buffer.id)
+		if handler[conf.cmd] then
+			handler[conf.cmd](obj, nil, nil, nAddNum)
 		end
-		if sum == 0 and cmd == "waitMiansi" then
-			local buffer = obj.buffer[ind]
-			local bufferCnt = delBuffer(obj, ind)
-			CombatImpl.addFrameBuffer(obj,buffer,CombatDefine.BUFFER_OP_DEL)
-			--local conf = BufferExcel.buffer[buffer.id]
-			local conf = GetBuffConfig(buffer.id)
-			local bufferID = conf.args[1]
-			if canAdd(obj,bufferID) then 
-				addBuffer(obj.pos,obj, bufferID)
-			end
-			return true
+	end
+
+	local isStatus,cmd,ind = isStatus(obj,{"miansi","waitMiansi"})
+	if not isStatus then
+		return
+	end
+	--免死逻辑
+	if cmd == "miansi" then
+		return true
+	end
+	if sum == 0 and cmd == "waitMiansi" then
+		local buffer = obj.buffer[ind]
+		local bufferCnt = delBuffer(obj, ind)
+		CombatImpl.addFrameBuffer(obj,buffer,CombatDefine.BUFFER_OP_DEL)
+		--local conf = BufferExcel.buffer[buffer.id]
+		local conf = GetBuffConfig(buffer.id)
+		local bufferID = conf.args[1]
+		if canAdd(obj,bufferID) then 
+			addBuffer(obj.pos,obj, bufferID)
 		end
+		return true
+	end
 end
 
 function checkBaohu(obj,value)
@@ -2150,6 +2334,10 @@ function onExtraCombatRecord(pos,value,param)
 	elseif param == "kill" then
 		obj.extraCombatRecord.kill = (obj.extraCombatRecord.kill or 0) + value
 	elseif param == "chenshui" then
-		obj.extraCombatRecord.kchenshuiill = (obj.extraCombatRecord.chenshui or 0) + value
+		obj.extraCombatRecord.chenshui = (obj.extraCombatRecord.chenshui or 0) + value
+	elseif param == "donghe" then
+		obj.extraCombatRecord.donghe = (obj.extraCombatRecord.donghe or 0) + value
+	elseif param == "gandian" then
+		obj.extraCombatRecord.gandian = (obj.extraCombatRecord.gandian or 0) + value
 	end
 end

+ 16 - 4
script/module/combat/CombatCalc.lua

@@ -76,7 +76,9 @@ local function getPojia(attacker, defender, skillConfig)
     local statusPoJia = BeSkill.getStatusPojia(attacker, defender)
 
     local pojia = attacker.attr[RoleDefine.POJIA] or 0
-    local total = hushiHujia + pojia + statusPoJia
+    local pojia_dk = defender.attr[RoleDefine.POJIA_DK] or 0
+
+    local total = hushiHujia + pojia + statusPoJia - pojia_dk
     total = total < 0 and 0 or total
     return total/10000
 end
@@ -259,7 +261,6 @@ end
 local function getBeSkillOutRate(attacker, defender, skillConfig, index, targets)
     -- 被动技能影响的输出率
     local outBeSkillRate = BeSkill.getOutAtkRate(attacker, defender)
-
     outBeSkillRate = 10000 - outBeSkillRate
     outBeSkillRate = outBeSkillRate < 0 and 0 or outBeSkillRate
 
@@ -285,6 +286,10 @@ local function getOutRate(attacker, defender, skillConfig, index, targets)
        hurtRate = hurtRate + CombatImpl.fightMode[4]
     end
 
+    local outBeSkillRate = BeSkill.getOutAtkRate2(attacker, skillConfig)
+    hurtRate = hurtRate + outBeSkillRate
+
+
     -- 战斗模式的伤害加成(死战)
     
     local fentanRate = getFentanRate(skillConfig, targets)
@@ -428,7 +433,7 @@ local function getExtraHurt(attacker, defender, skillConfig)
 end
 
 function initAttacker(attacker)
-    if attacker.isPet then
+    if attacker.isPet or attacker.isElf then
         return
     end
     attacker.isBaoji = nil
@@ -534,7 +539,7 @@ function calcPhyHurt(attacker, index, targets, skillConfig)
         hurt = hurt * 0.5
     end
 
-
+    hurt = math.max(hurt, 1)
     CombatObj.updateValue(attacker, RoleDefine.HURT_COMBAT_NOW, hurt)
     return hurt, flag
 end
@@ -679,6 +684,13 @@ function calcHurt(attacker, index, targets, skillConfig)
         return attacker.hurt or skillConfig.hurtRate[1], 0
     end
 
+    -- 精灵技能
+    if skillConfig.type == CombatDefine.SKILL_TYPE77 then
+        local atk = CombatObj.getValue(attacker, RoleDefine.ATK)
+        return atk * (skillConfig.hurtRate[1] / 10000), 0
+    end
+
+
     if not skillConfig.otherArgs.absoluteHit and isShanbi(attacker, index, targets) then
         local flag = 0
         flag = Util.setBit(flag, CombatDefine.FLAG_SHANBI)

+ 27 - 2
script/module/combat/CombatDefine.lua

@@ -13,6 +13,11 @@ DEFEND_SIDE 		= 2 	-- 右方
 --攻守站位
 SIDE2POS = {[0] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20},[1] = {1,2,3,4,5,6,7,8,9,10},[2] = {11,12,13,14,15,16,17,18,19,20}}
 SIDE2HELPPOS = {[0] = {21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40},[1] = {21,22,23,24,25,26,27,28,29,30},[2] = {31,32,33,34,35,36,37,38,39,40}}
+
+-- 精灵站位
+SIDE2ELFPOS = {[0] = {41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60}, [1] = {41,42,43,44,45,46,47,48,49,50}, [2] = {51,52,53,54,55,56,57,58,59,60}}
+
+
 --前,中,后排目标选择策略 begin
 ROW2POS = {
     [1] ={
@@ -124,6 +129,10 @@ COMBAT_BACKUP_POS   = 10    --援军站位
 COMBAT_HELP_CNT     = 10    -- 单边出战辅助对象最大个数
 COMBAT_HELP_ALL_CNT = 20    -- 两边出战辅助对象最大个数
 
+COMBAT_ELF_NOW_CNT  = 4     -- 单边出战精灵对象当前最大数量
+COMBAT_ELF_CNT      = 10    -- 单边出战精灵对象最大数量
+COMBAT_ELF_ALL_CNT  = 20    -- 两边出战精灵对象最大数量
+
 
 -- 战斗结果:0-平局 1-攻方胜利 2-守方胜利
 RESULT_TIE = 0
@@ -139,6 +148,10 @@ SKILL_TYPE5 = 5 --技能包攻击(按顺序生效技能包中其中一个)
 SKILL_TYPE6 = 6 --技能包攻击(技能包全部生效)
 SKILL_TYPE7 = 7 --技能包攻击(随机生效技能包中其中一个)
 
+SKILL_TYPE77 = 77 -- 精灵技能类型
+
+
+
 --buffer时效类型
 BUFFER_TYPE1			= 1		-- 即时buffer
 BUFFER_TYPE2			= 2		-- 普通buffer
@@ -192,8 +205,11 @@ COMBAT_TYPE29 = 29 --新天梯赛
 COMBAT_TYPE30 = 30 --主线闯关二队
 COMBAT_TYPE31 = 31 --幽暗禁地
 COMBAT_TYPE32 = 32 --诸神圣域
+COMBAT_TYPE33 = 33 -- 战区争霸
+COMBAT_TYPE34 = 34 --节日活动BOSS
+COMBAT_TYPE35 = 35 --巅峰战场
 
-
+-- 如果新加阵容的 teamType 和 COMBAT_TYPE1的 teamType 一样, 则需要在下方增加
 -- 一个英雄不能同时上阵的阵容列表, 即一个英雄在key代表阵容上阵后,就不能同时在value列表中的战斗阵容里上阵
 COMBAT_EXCLUSION_LIST = {
     [COMBAT_TYPE1] = {COMBAT_TYPE30},
@@ -210,12 +226,14 @@ COMBAT_EXCLUSION_LIST = {
 
 
 
-COMBAT_TYPE_MAX = 24 --阵容最大数
+COMBAT_TYPE_MAX = 35 --阵容最大数
 --对象类型
 COMBAT_OBJ_TYPE1 = 1 --玩家 
 COMBAT_OBJ_TYPE2 = 2 --怪物
 COMBAT_OBJ_TYPE3 = 3 --BOSS
 
+COMBAT_OBJ_TYPE99 = 99 --精灵
+
 --职业枚举
 JOB_TYPE1 = 1 --虎卫
 JOB_TYPE2 = 2 --猛将
@@ -256,6 +274,9 @@ end
 --辅助对象站位
 HELP_TYPE0 = 0  --武将
 HELP_TYPE1 = 1  --魔兽
+HELP_TYPE2 = 2 -- 精灵
+
+
 function getHelpPos(side,type)
     return SIDE2HELPPOS[side][type]
 end
@@ -265,6 +286,10 @@ CAMP_ALL = 6
 PET_ATKPOS = 21
 PET_DEFPOS = 31
 
+
+ELF_MIN_POS = 41 -- 精灵位置最小值
+ELF_MAX_POS = 60 -- 精灵位置最大值
+
 --阵营枚举
 CAMP_TYPE1 = 1 --恶魔
 CAMP_TYPE2 = 2 --圣堂

+ 113 - 14
script/module/combat/CombatImpl.lua

@@ -18,6 +18,7 @@ local SkillExcel = require("excel.skill").skill
 
 objList 		= objList or {}
 helpList		= helpList or {}
+elfList			= elfList or {}
 attackOrder		= attackOrder or {}		-- 出手次序 [index]->pos
 round 			= round or 1 			-- 当前回合
 attackIndex 	= attackIndex or 1 		-- 当前进攻对象的index
@@ -55,11 +56,17 @@ fightMode       = {0,0,0,0}
 initBackup		= {0,0}
 comboPosList	= {}
 totalHurt		 = 0
+useZhuijiObjList = {} --本场战斗使用过追击的英雄列表
+heroSpeedList = { -- 对战双方第一回合所有英雄的速度值列表
+	--[CombatDefine.ATTACK_SIDE] = {},
+	--[CombatDefine.DEFEND_SIDE] = {},
+} 
 
 
 function init(type)
 	Util.initTable(objList)
 	Util.initTable(helpList)
+	Util.initTable(elfList)
 	Util.initTable(attackOrder)
 	Util.initTable(result)
 	Util.initTable(skillUseList)
@@ -75,6 +82,8 @@ function init(type)
 	Util.initTable(comboList)
 	Util.initTable(initBackup)
     Util.initTable(frameReviceList)
+	Util.initTable(useZhuijiObjList)
+	Util.initTable(heroSpeedList)
 	round = 0
 	attackIndex = nil
 	isFanji = false
@@ -179,7 +188,11 @@ function setData(pos, hero)
     else
        obj.hurtType = MonsterExcel[obj.id].hurtType
 	   if not obj.hurtType then
-			obj.hurtType = BattleMonsterExcel[obj.id].hurtType or 0
+			if BattleMonsterExcel[obj.id] then
+				obj.hurtType = BattleMonsterExcel[obj.id].hurtType or 0
+			else
+				obj.hurtType = 0
+			end
 	   end
     end
 
@@ -216,6 +229,21 @@ function setHelp(side,helpType,help)
 	helpList[pos] = obj
 end
 
+function setElf(pos, elf)
+	local elfObj = CombatObj.elfs[pos]
+	CombatObj.initElf(elfObj)
+
+	elfObj.id = elf.id
+	elfObj.type = elf.type
+	elfObj.body = elf.body or 0
+	elfObj.head = elf.head or 0
+	elfObj.quality = elf.quality or 1
+	elfObj.skillList = elf.skillList or {}
+	elfObj.beSkillList = elf.beSkillList or {}
+	elfList[pos] = elfObj
+end
+
+
 function setMaxRound(value)
 	maxRound = value
 end
@@ -238,20 +266,40 @@ end
 
 local function cmp(a,b)
 	if a.helpType ~= CombatDefine.HELP_TYPE0 or b.helpType ~= CombatDefine.HELP_TYPE0 then
+		-- if a.helpType == CombatDefine.HELP_TYPE0 then
+		-- 	return false
+		-- elseif b.helpType == CombatDefine.HELP_TYPE0 then
+		-- 	return true
+		-- else
+        --     local aSpeed = a.speed or 0
+	    --     local bSpeed = b.speed or 0
+	    --     if aSpeed > bSpeed then
+	    --     	return true
+	    --     elseif aSpeed == bSpeed then
+	    --     	return a.pos < b.pos
+	    --     else
+	    --     	return false
+	    --     end 
+		-- end
+
 		if a.helpType == CombatDefine.HELP_TYPE0 then
 			return false
 		elseif b.helpType == CombatDefine.HELP_TYPE0 then
 			return true
+		elseif a.helpType == CombatDefine.HELP_TYPE1 and b.helpType == CombatDefine.HELP_TYPE2 then
+			return true
+		elseif a.helpType == CombatDefine.HELP_TYPE2 and b.helpType == CombatDefine.HELP_TYPE1 then
+			return false
 		else
             local aSpeed = a.speed or 0
-	        local bSpeed = b.speed or 0
-	        if aSpeed > bSpeed then
-	        	return true
-	        elseif aSpeed == bSpeed then
-	        	return a.pos < b.pos
-	        else
-	        	return false
-	        end 
+			local bSpeed = b.speed or 0
+			if aSpeed > bSpeed then
+				return true
+			elseif aSpeed == bSpeed then
+				return a.pos < b.pos
+			else
+				return false
+			end
 		end
 	end
 	local aSpeed = getValue(a, RoleDefine.SPEED)
@@ -291,7 +339,13 @@ local function canAttack(obj)
 	elseif obj.helpType == CombatDefine.HELP_TYPE1 then
 		return petCD == 0
 	elseif obj.helpType == CombatDefine.HELP_TYPE2 then
-
+		for i = 1,#obj.skillList do
+			local skill = obj.skillList[i]
+			if (skill[3] == 0 or (skill[2] - round) % skill[3] == 0) and Skill.SkillCondCheck(obj, skill[1]) then
+				return true
+			end
+		end
+		return false
 	elseif obj.helpType == CombatDefine.HELP_TYPE3 then
 
 	elseif obj.helpType == CombatDefine.HELP_TYPE4 then
@@ -316,6 +370,12 @@ function initAttackOrder()
                atkSpeed = speed
                atkSide = obj.side
             end
+
+			if round == 1 or not next(heroSpeedList) then
+				heroSpeedList[obj.side] = heroSpeedList[obj.side] or {speedVal = 0, objCnt = 0, speedAvVal = 0}
+				heroSpeedList[obj.side].speedVal = heroSpeedList[obj.side].speedVal + speed
+				heroSpeedList[obj.side].objCnt = heroSpeedList[obj.side].objCnt + 1
+			end
 		end
 	end
 
@@ -326,11 +386,34 @@ function initAttackOrder()
 
             obj.speed = nil
             if obj.side == atkSide then
-               obj.speed = atkSpeed
+				obj.speed = atkSpeed
             end
 		end
 	end
 
+	if round == 1 and heroSpeedList[CombatDefine.ATTACK_SIDE] and heroSpeedList[CombatDefine.DEFEND_SIDE] then
+		local atkList = heroSpeedList[CombatDefine.ATTACK_SIDE]
+		atkList.speedAvVal = math.floor(atkList.speedVal / atkList.objCnt)
+
+		local defList = heroSpeedList[CombatDefine.DEFEND_SIDE]
+		defList.speedAvVal = math.floor(defList.speedVal / defList.objCnt)
+	end
+
+	-- 精灵
+	for _,pos in ipairs(CombatDefine.SIDE2ELFPOS[0]) do
+		local elfObj = elfList[pos]
+		if elfObj and canAttack(elfObj) then
+			attackOrder[#attackOrder + 1] = elfObj
+
+            -- if elfObj.side == atkSide then
+			-- 	elfObj.speed = atkSpeed
+            -- end
+
+			elfObj.speed = heroSpeedList[elfObj.side] and heroSpeedList[elfObj.side].speedAvVal or 0
+		end
+	end
+
+
 	table.sort(attackOrder,cmp)
 	firstAttack = {true,true}
 end
@@ -544,8 +627,15 @@ function getSkillID(obj)
 				break
 			end
 		end
-	elseif obj.helpType == CombatDefine.HELP_TYPE2 then
-
+	elseif obj.helpType == CombatDefine.HELP_TYPE2 then -- 精灵
+		for i = 1,#obj.skillList do
+			local skill = obj.skillList[i]
+			if (skill[3] == 0 or (skill[2] - round) % skill[3] == 0) and  Skill.SkillCondCheck(obj, skill[1]) then
+				skillID = skill[1]
+				skill[2] = round + skill[3]
+				break
+			end
+		end
 	elseif obj.helpType == CombatDefine.HELP_TYPE3 then
 
 	elseif obj.helpType == CombatDefine.HELP_TYPE4 then
@@ -778,7 +868,8 @@ function calcFrame()
     	-- buff作用效果
         --skillID = 10131
 		if skillID then
-        	Skill.use(attacker,skillID,mpAtkRate)			
+        	Skill.use(attacker,skillID,mpAtkRate)
+			CombatBuff.BuffHandleAfterSkill(attacker)
         	addObjResultOut(attacker,round)
 		end	
 	end
@@ -1075,6 +1166,8 @@ function setObjResult(pos,value)
 		obj = helpList[pos]
 	elseif pos == CombatDefine.PET_DEFPOS then
 		obj = helpList[pos]
+	elseif CombatDefine.ELF_MIN_POS <= pos and CombatDefine.ELF_MAX_POS >= pos then
+		obj = elfList[pos]
 	end
 	if not obj then
 		return
@@ -1112,6 +1205,12 @@ function comboAgain(obj, type, hurtRate, comboSkillID, skip)
     if skillID then
        comboType = type
        comboHurtRate = hurtRate
+	   if type == 999 then --追击
+			local objPos = obj.pos
+			local objTag = obj.uuid or obj.id
+			useZhuijiObjList[objPos] = {}
+			useZhuijiObjList[objPos][objTag] = (useZhuijiObjList[objPos][objTag] or 0) + 1
+	   end
        Skill.use(obj, skillID)
        comboType = 0
     end

+ 207 - 13
script/module/combat/CombatLogic.lua

@@ -55,18 +55,20 @@ local EquipLogic = require("equip.EquipLogic")
 local ItemDefine = require("bag.ItemDefine")
 local HeroLogic = require("hero.HeroLogic")
 local XingYaoGongMing = require("xingYaoMen.XingYaoGongMing")
-local MoshouLogic = require("moshou.MoshouLogic")
+-- local MoshouLogic = require("moshou.MoshouLogic")
 local LostTempleCombatLogic = require("lostTemple.lostTempleCombatLogic")
 local SkinExcel = require("excel.skin")
 local BattleLogic = require("battle.BattleLogic")
 local HeroExclusiveWeapon = require("hero.HeroExclusiveWeapon")
+local ItemConfig = require("excel.item").item
+local ElfLogic = require("elf.ElfLogic")
 
 -- 用于在切磋时取目标玩家db数据中的计算属性数据, 如果在 RoleAttr.calcHeroGrid中用到了,需要加到这个里面
 FieldsCombat = {
 	lv = 1, name = 1, head = 1, headFrame = 1, unionUuid = 1, lastLogoutTime = 1, 
 	combatHero = 1, heroBag = 1, moshou = 1, technology=1, chengjiu=1, realmLv = 1, talismanData = 1,
 	headList = 1, headFrameList = 1, bodyList = 1, chenghaoList = 1,animationList =1,backgroundList =1,
-	skinBag = 1, relic = 1, heroPubData = 1,
+	skinBag = 1, relic = 1, heroPubData = 1, elfData = 1,
 }
 
 COMBAT_CACHE = COMBAT_CACHE or {}
@@ -160,11 +162,11 @@ function getCombatObjList(human, side, combatType, args)
 	if type(args) == "table" then
 		if side == CombatDefine.ATTACK_SIDE then
 			if args.attacker then
-				return args.attacker, args.atkHelp, args.atkRBase, args.atkFormation,args.atkJiban
+				return args.attacker, args.atkHelp, args.atkRBase, args.atkFormation,args.atkJiban,args.atkElfList
 			end
 		else
 			if args.defender then
-				return args.defender, args.defHelp, args.defRBase, args.defFormation,args.defJiban
+				return args.defender, args.defHelp, args.defRBase, args.defFormation,args.defJiban, args.defElfList
 			end
 		end
 	end
@@ -172,19 +174,19 @@ function getCombatObjList(human, side, combatType, args)
 	if not moduleFn then return end
 
 	if moduleFn.getCombatObjList then
-		local objList, helpList, rolebase, formation,jiban = moduleFn.getCombatObjList(human, side, args, combatType)
+		local objList, helpList, rolebase, formation,jiban, elfList = moduleFn.getCombatObjList(human, side, args, combatType)
 		if objList then
-			return objList, helpList, rolebase ,formation,jiban
+			return objList, helpList, rolebase ,formation,jiban, elfList
 		end
 	end
 
 	local monsterOutID, zhandouli = getCombatMonsterOutID(human, side, combatType, args)
 	if monsterOutID then
-		local objList, helpList, rolebase, formation, jiban = getMonsterObjList(monsterOutID, nil, args)
+		local objList, helpList, rolebase, formation, jiban, elfList = getMonsterObjList(monsterOutID, nil, args)
 		if zhandouli then 
 			rolebase.zhandouli = zhandouli
 		end
-		return objList, helpList, rolebase,formation,jiban
+		return objList, helpList, rolebase,formation,jiban, elfList
 	end
 
     if moduleFn.getHumanObjList then
@@ -280,6 +282,20 @@ function getPos(side, index)
 	end
 end
 
+-- 通过位置确定阵营
+function getSideByPos(helpType, pos)
+	if helpType == CombatDefine.HELP_TYPE0 then
+		return pos > CombatDefine.COMBAT_HERO_CNT and CombatDefine.DEFEND_SIDE or CombatDefine.ATTACK_SIDE
+	elseif helpType == CombatDefine.HELP_TYPE1 then
+		return pos >= CombatDefine.PET_DEFPOS and CombatDefine.DEFEND_SIDE or CombatDefine.ATTACK_SIDE
+	elseif helpType == CombatDefine.HELP_TYPE2 then
+		local atkElfMaxPos = CombatDefine.COMBAT_HERO_ALL_CNT + CombatDefine.COMBAT_HELP_ALL_CNT + CombatDefine.COMBAT_ELF_CNT
+		return pos > atkElfMaxPos and CombatDefine.DEFEND_SIDE or CombatDefine.ATTACK_SIDE
+	else
+		assert(false, "helpType 错误")
+	end
+end
+
 function getIndexByPos(side, pos)
 	if side == CombatDefine.ATTACK_SIDE then
 		return pos
@@ -526,6 +542,30 @@ function getMonsterObjList(monsterOutID, objType, args)
 	return objList, nil, rolebase,formation,jiban
 end
 
+-- 创建战斗精灵对象
+function createElfObj(human, elfId, pos)
+	local itemCfg = ItemConfig[elfId]
+	local elfObj = {}
+	elfObj.id = elfId
+	elfObj.type = CombatDefine.COMBAT_OBJ_TYPE99
+	elfObj.isElf = true
+	elfObj.head = itemCfg and itemCfg.icon or 0
+	elfObj.body = itemCfg and itemCfg.icon or 0
+
+	elfObj.attrs = {}
+
+	local skillId = ElfLogic.GetElfSkill(human, elfId)
+	local skillCfg = Skill.GetSkillConfig(skillId)
+	if not skillCfg then
+		return
+	end
+
+	elfObj.skillList = {
+		[1] = {skillId, pos, skillCfg.cd[2] or 0 }
+	}
+
+	return elfObj
+end
 
 -- 获取human出战英雄列表 objList, helpList, rolebase, formation
 function getHumanObjList(human, combatType)
@@ -552,7 +592,21 @@ function getHumanObjList(human, combatType)
 	local pet = MoshouLogic.createCombatMoshow(human,combatType)
 	helpList[CombatDefine.HELP_TYPE1] = pet
 	local rolebase = createRoleBaseByDB(human.db, zhandouli)
-	return objList, helpList, rolebase,formation,jiban
+
+	-- 精灵
+	local combatElf = combatHeroDB.elfList
+	local elfList = {}
+	if combatElf then
+		for i=1, CombatDefine.COMBAT_ELF_CNT do
+			local elfId = combatElf[i]
+			local elfObj = createElfObj(human, elfId, i)
+			if elfObj then
+				elfList[i] = elfObj
+			end
+		end
+	end
+
+	return objList, helpList, rolebase,formation,jiban, elfList
 end
 
 
@@ -668,6 +722,33 @@ function fontCombatHelpNet(net, help)
 end
 
 
+-- 封装辅助对象
+function fontCombatElfpNet(net, elf)
+	net.pos = elf.pos
+	net.id = elf.id or 0
+	net.head = elf.head or 0
+	net.body = elf.body or 0
+
+    net.skill[0] = 0
+	local skillId = elf.skillList[1][1]
+	local skillConfig = Skill.GetSkillConfig(skillId)
+    if skillConfig then
+       net.skill[1].id = skillId
+       net.skill[1].icon = skillConfig.icon
+       net.skill[1].name = skillConfig.name
+       net.skill[1].desc = skillConfig.desc
+       net.skill[1].lv = skillConfig.skillLV or 0
+       net.skill[1].index = 0
+       net.skill[1].state = 2
+       net.skill[0] = 1
+    end
+    
+	net.args[0] = 0
+	return true
+end
+
+
+
 -- 封装战斗技能信息
 function fontCombatSkillNet(skillNet, skillID)
 	--local skillConfig = SkillExcel.skill[skillID]
@@ -797,7 +878,14 @@ local function sendCombatBegin(human, combatInfo, isLogin)
 		if fontCombatHelpNet(msgRet.helps[msgRet.helps[0] + 1], help) then
 			msgRet.helps[0] = msgRet.helps[0] + 1
 		end
-	end	
+	end
+
+	for _, elf in pairs(combatInfo.elfList or {}) do
+		if fontCombatElfpNet(msgRet.helps[msgRet.helps[0] + 1], elf) then
+			msgRet.helps[0] = msgRet.helps[0] + 1
+		end
+	end
+
 	msgRet.skillList[0] = 0
 	for skillID in pairs(combatInfo.skillUseList) do
 		if fontCombatSkillNet(msgRet.skillList[msgRet.skillList[0] + 1], skillID) then
@@ -996,6 +1084,12 @@ function fontFinishResultNet(net, obj)
        net.body = heroConfig and heroConfig.body.."" or ""
        net.head = heroConfig and heroConfig.head or 0
        net.grade = heroConfig and heroConfig.grade or 0
+	elseif obj.type == CombatDefine.COMBAT_OBJ_TYPE99 then
+		local itemCfg = ItemConfig[obj.id]
+		net.name = itemCfg and itemCfg.name or ""
+		net.body = itemCfg and itemCfg.icon.."" or ""
+		net.head = itemCfg and itemCfg.icon or 0
+		net.grade = 0
     else
        net.name = monsterConfig and monsterConfig.name or ""
        net.body = monsterConfig and monsterConfig.body.."" or ""
@@ -1066,6 +1160,17 @@ function fontCombatFinish(dataNet, combatInfo, isQuick)
 			fontFinishResultNet(net, pet)
 		end
 	end
+
+	-- 出战精灵
+    for _,pos in ipairs(CombatDefine.SIDE2ELFPOS[0]) do
+		local elfObj = combatInfo.elfList and combatInfo.elfList[pos]
+		if elfObj then
+			dataNet.result[0] = dataNet.result[0] + 1
+			local net = dataNet.result[dataNet.result[0]]
+			fontFinishResultNet(net, elfObj)
+		end
+	end
+
 	-- 奖励
 	local rewardItem = combatInfo.rewardItem
     local len = 0 
@@ -1115,6 +1220,21 @@ local function getMonsterBossName(param)
 	end
 end
 
+-- 从某方战斗英雄阵容中获取某个属性的最大值
+local function getHeroAttrMaxVal(side, attrId)
+	local maxVal = 0
+	for _, pos in ipairs(CombatDefine.SIDE2POS[side]) do
+		local obj = CombatImpl.objList[pos]
+		if obj then
+			local attrVal = CombatObj.getValue(obj,attrId)
+			if attrVal > maxVal then
+				maxVal = attrVal
+			end
+		end
+	end
+	return maxVal
+end
+
 -- 在各种战前加成后,重新设置血量
 function recalcHpFightBegin(human, combatType, cbParam)
 	for i = 1,CombatDefine.COMBAT_HERO_CNT do
@@ -1158,6 +1278,46 @@ function recalcHpFightBegin(human, combatType, cbParam)
 	end
 end
 
+
+-- 精灵继承英雄属性列表, key为属性Id, value为继承属性值的倍数
+local inheritAttrList = {
+	[RoleDefine.ATK] = 1,
+}
+-- 精灵继承英雄部分属性
+function ElfInheritHeroAttr()
+	local attrList = {}
+
+	local function genAttrVal()
+		for attrId, mul in pairs(inheritAttrList) do
+			attrList[attrId] = { [CombatDefine.ATTACK_SIDE] = 0, [CombatDefine.DEFEND_SIDE] = 0,}
+			local atkMaxVal = getHeroAttrMaxVal(CombatDefine.ATTACK_SIDE, attrId)
+			local defMaxVal = getHeroAttrMaxVal(CombatDefine.DEFEND_SIDE, attrId)
+			attrList[attrId][CombatDefine.ATTACK_SIDE] = atkMaxVal * mul
+			attrList[attrId][CombatDefine.DEFEND_SIDE] = defMaxVal * mul
+		end
+	end
+
+	local function updateELfAttr(elfObj, side)
+		for attrId, valData in pairs(attrList) do
+			CombatObj.updateValue(elfObj, attrId, valData[side] or 0)
+		end
+	end
+
+	for _, pos in ipairs(CombatDefine.SIDE2ELFPOS[CombatDefine.ALL]) do
+		local elfObj = CombatImpl.elfList[pos]
+		if elfObj then
+			if next(inheritAttrList) and not next(attrList) then
+				genAttrVal()
+			end
+
+			local elfSide = getSideByPos(CombatDefine.HELP_TYPE2, pos)
+			updateELfAttr(elfObj, elfSide)
+		end
+	end
+end
+
+
+
 --战前加属性(包括各系统,被动技能,阵营光环)
 function onFightBegin(human, combatType, cbParam, param)
 	local moduleFn = getModule(combatType)
@@ -1169,6 +1329,7 @@ function onFightBegin(human, combatType, cbParam, param)
 	SkinLogic.onFightBegin(human) -- 处理皮肤属性
 	CombatPosLogic.onFightBegin(human)
 	recalcHpFightBegin(human, combatType, cbParam)
+	ElfInheritHeroAttr()
 end
 
 
@@ -1202,6 +1363,21 @@ local function setHelp(helpList, side)
 	end
 end
 
+-- 设置精灵出战
+local function setElf(elfList, side)
+	if not elfList or not next(elfList) then
+		return
+	end
+
+	for index = 1, CombatDefine.COMBAT_ELF_CNT do
+		local elfObj = elfList[index]
+		if elfObj then
+			local pos = CombatDefine.SIDE2ELFPOS[side][index]
+			CombatImpl.setElf(pos, elfObj)
+		end
+	end
+end
+
 -- 初始combatInfo
 local function initCombatInfo(human, combatType, mapID)
 	local combatInfo = {}
@@ -1222,6 +1398,7 @@ local function initCombatInfo(human, combatType, mapID)
 	combatInfo.bufferUseList = nil 	-- 战斗buff
 	combatInfo.objList = nil  		-- 战斗英雄列表
 	combatInfo.helpList = nil  		-- 战斗魔兽列表
+	combatInfo.elfList = nil  		-- 战斗精灵列表
 	combatInfo.rewardItem = {} 		-- 奖励
 	combatInfo.endParam = nil 		-- 额外参数
 	combatInfo.isVideo = nil 		-- 是否录像	
@@ -1243,6 +1420,7 @@ local function copyToCombatInfo(combatInfo)
 	combatInfo.bufferUseList = Util.copyTable(CombatImpl.bufferUseList)
 	combatInfo.objList = Util.copyTable(CombatImpl.objList)	
 	combatInfo.helpList = Util.copyTable(CombatImpl.helpList)
+	combatInfo.elfList = Util.copyTable(CombatImpl.elfList)
 	combatInfo.totalAtkCnt = CombatImpl.totalAtkCnt
 end
 
@@ -1265,10 +1443,10 @@ function combatBegin(human, mapID, param, combatType, cbParam, isSaodang)
     -- 获得地图ID
     CombatImpl.init(combatType)
     mapID = getMapID(human, combatType, param)
-	local defender, defHelp, defRBase,defFormation,defJiban = getCombatObjList(human, CombatDefine.DEFEND_SIDE, combatType, param)
-	local attacker, atkHelp, atkRBase, atkFormation,atkJiban
+	local defender, defHelp, defRBase,defFormation,defJiban, defElfList = getCombatObjList(human, CombatDefine.DEFEND_SIDE, combatType, param)
+	local attacker, atkHelp, atkRBase, atkFormation,atkJiban, atkElfList
 	if defender then
-		attacker, atkHelp, atkRBase, atkFormation,atkJiban = getCombatObjList(human, CombatDefine.ATTACK_SIDE, combatType, param)
+		attacker, atkHelp, atkRBase, atkFormation,atkJiban, atkElfList = getCombatObjList(human, CombatDefine.ATTACK_SIDE, combatType, param)
 	end		
 
 	if not (attacker and next(attacker)) then
@@ -1317,6 +1495,10 @@ function combatBegin(human, mapID, param, combatType, cbParam, isSaodang)
 	setCombatInfo(defFormation, defender, CombatDefine.DEFEND_SIDE)
 	setHelp(atkHelp, CombatDefine.ATTACK_SIDE)
 	setHelp(defHelp, CombatDefine.DEFEND_SIDE)
+
+	setElf(atkElfList, CombatDefine.ATTACK_SIDE)
+	setElf(defElfList, CombatDefine.DEFEND_SIDE)
+
 	CombatImpl.setMaxRound(combatInfo.maxRound)
 	CombatImpl.setFightMode(combatInfo.fightMode)
 	--需要对技能特殊处理的(比如不重置cd)
@@ -1376,6 +1558,10 @@ function combatGm(human,mapID,atkFormation,attacker,defFormation,defender,atkPet
 	setCombatInfo(defFormation,defender, CombatDefine.DEFEND_SIDE)
 	setHelp({atkPet}, CombatDefine.ATTACK_SIDE)
 	setHelp({defPet}, CombatDefine.DEFEND_SIDE)
+
+	setElf({}, CombatDefine.ATTACK_SIDE)
+	setElf({}, CombatDefine.DEFEND_SIDE)
+
 	combatInfo.maxRound = getMaxRound(human,combatType)
 	CombatImpl.setMaxRound(combatInfo.maxRound)
     CombatImpl.setFightMode(combatInfo.fightMode)
@@ -1416,6 +1602,10 @@ function combatGuide(human, atkFormation,attacker,defFormation,defender,atkPet,d
 	setCombatInfo(defFormation,defender, CombatDefine.DEFEND_SIDE)
 	setHelp({atkPet}, CombatDefine.ATTACK_SIDE)
 	setHelp({defPet}, CombatDefine.DEFEND_SIDE)
+
+	setElf({}, CombatDefine.ATTACK_SIDE)
+	setElf({}, CombatDefine.DEFEND_SIDE)
+
 	combatInfo.maxRound = getMaxRound(human, combatType)
 	CombatImpl.setMaxRound(combatInfo.maxRound)
     CombatImpl.setFightMode(combatInfo.fightMode)
@@ -1453,6 +1643,10 @@ function combatVedio(human, atkFormation, attacker,defFormation,defender,atkPet,
 	setCombatInfo(defFormation,defender, CombatDefine.DEFEND_SIDE)
 	setHelp({atkPet}, CombatDefine.ATTACK_SIDE)
 	setHelp({defPet}, CombatDefine.DEFEND_SIDE)
+
+	setElf({}, CombatDefine.ATTACK_SIDE)
+	setElf({}, CombatDefine.DEFEND_SIDE)
+
 	combatInfo.maxRound = getMaxRound(human, combatType)
 	CombatImpl.setMaxRound(combatInfo.maxRound)
     CombatImpl.setFightMode(combatInfo.fightMode)

+ 280 - 0
script/module/combat/CombatLogicCS.lua

@@ -0,0 +1,280 @@
+-- 战斗逻辑(跨服)
+
+local CombatExcel = require("excel.combat")
+local Config = require("Config")
+local Util = require("common.Util")
+local CombatImpl = require("combat.CombatImpl")
+local CombatDefine = require("combat.CombatDefine")
+local CombatPosLogic = require("combat.CombatPosLogic")
+local CombatPetCalc = require("combat.CombatPetCalc")
+local JibanLogic = require("combat.JibanLogic")
+local BeSkill = require("combat.BeSkill")
+local CombatObj = require("combat.CombatObj")
+local RoleDefine = require("role.RoleDefine")
+local CombatLogic = require("combat.CombatLogic")
+
+-- 初始combatInfo
+local function initCombatInfo(human, combatType, mapID)
+	local combatInfo = {}
+	combatInfo.time = os.time() 	-- 战斗时间
+	combatInfo.passTime = 0 	    -- 客户端经过的时间
+	combatInfo.type = combatType 	-- 战斗类型
+	combatInfo.mapID = mapID  		-- 地图
+	combatInfo.posAttr = {}			-- 阵法属性
+	combatInfo.jiban = {}			-- 阵法属性
+	combatInfo.attacker = nil  		-- 攻方基础角色信息 roleBase
+	combatInfo.defender = nil 		-- 守方基础角色信息 roleBase
+	combatInfo.atkJiban = nil 		-- 攻方羁绊英雄
+	combatInfo.defJiban = nil 		-- 守方羁绊英雄	
+	combatInfo.isWin = nil 			-- 战斗结果
+	combatInfo.result = nil 		-- 战斗帧
+	combatInfo.skillUseList = nil 	-- 战斗技能
+	combatInfo.cmdUseList = nil 	-- 战斗技能命令
+	combatInfo.bufferUseList = nil 	-- 战斗buff
+	combatInfo.objList = nil  		-- 战斗英雄列表
+	combatInfo.helpList = nil  		-- 战斗魔兽列表
+	combatInfo.elfList = nil  		-- 战斗精灵列表
+	combatInfo.rewardItem = {} 		-- 奖励
+	combatInfo.endParam = nil 		-- 额外参数
+	combatInfo.isVideo = nil 		-- 是否录像	
+	combatInfo.videoUuid = nil 		-- 录像uuid
+	combatInfo.panelID = nil 		-- 返回界面(特殊)
+	combatInfo.maxRound = nil 		-- 最大会合数
+	combatInfo.fightMode = nil 		-- 战斗模式
+	human.combat = combatInfo
+	return combatInfo
+end
+
+local function getMapID(combatType)
+    local mapID = nil
+    local config = CombatExcel.combat[combatType]
+    mapID = config.mapID == 0 and 1001 or config.mapID
+    return mapID
+end
+
+--获取战斗最大回合数
+local function getMaxRound(combatType)
+	local config = CombatExcel.combat[combatType]
+	if config and config.maxRound and config.maxRound > 0 then
+		return config.maxRound
+	end
+	return CombatDefine.COMBAT_ROUND_MAX
+end
+
+--获取战斗模式
+local function getFightMode(combatType)
+	local config = CombatExcel.combat[combatType]
+	if config.fightMode[1] == CombatDefine.FIGHT_MODE1 or config.fightMode[1] == CombatDefine.FIGHT_MODE3 then
+		return config.fightMode
+	end
+end
+
+
+local function setCombatInfo(formation,objList, side)
+	for index = 1, CombatDefine.COMBAT_HERO_CNT do
+		local obj = objList[index]
+		if obj then
+				-- 出战英雄站位
+			if CombatPosLogic.checkPos(formation,index, side) then
+				local pos = CombatDefine.SIDE2POS[side][index]
+				obj.formationPos = index
+				CombatImpl.setData(pos, obj)
+			end
+		end
+	end
+end
+
+-- 设置辅助对象出战
+local function setHelp(helpList, side)
+	if not helpList then return end
+	for k,v in pairs(helpList) do
+		if k ==  CombatDefine.HELP_TYPE1 then
+			CombatPetCalc.calcGrowArgs(v)
+			CombatPetCalc.clacBuffArgs(v)
+		end
+		CombatImpl.setHelp(side,k,v)
+	end
+end
+
+-- 设置精灵出战
+local function setElf(elfList, side)
+	if not elfList or not next(elfList) then
+		return
+	end
+
+	for index = 1, CombatDefine.COMBAT_ELF_CNT do
+		local elfObj = elfList[index]
+		if elfObj then
+			local pos = CombatDefine.SIDE2ELFPOS[side][index]
+			CombatImpl.setElf(pos, elfObj)
+		end
+	end
+end
+
+
+-- 为了战斗回放,某些数据需要保存
+local function copyToCombatInfo(combatInfo)
+	combatInfo.isWin = CombatImpl.result.isWin
+	combatInfo.result = Util.copyTable(CombatImpl.result)
+	combatInfo.result.round = CombatImpl.round
+	combatInfo.skillUseList = Util.copyTable(CombatImpl.skillUseList)
+	combatInfo.cmdUseList = Util.copyTable(CombatImpl.cmdUseList)
+	combatInfo.bufferUseList = Util.copyTable(CombatImpl.bufferUseList)
+	combatInfo.objList = Util.copyTable(CombatImpl.objList)	
+	combatInfo.helpList = Util.copyTable(CombatImpl.helpList)
+	combatInfo.elfList = Util.copyTable(CombatImpl.elfList)
+	combatInfo.totalAtkCnt = CombatImpl.totalAtkCnt
+end
+
+
+-- 根据阵营和下标获取对战位置
+local function getPos(side, index)
+	if side == CombatDefine.ATTACK_SIDE then
+		return index
+	elseif side == CombatDefine.DEFEND_SIDE then
+		return index + CombatDefine.COMBAT_HERO_CNT
+	else
+		assert()
+	end
+end
+
+-- 在各种战前加成后,重新设置血量
+local function recalcHpFightBegin(human, combatType, cbParam)
+	for i = 1,CombatDefine.COMBAT_HERO_CNT do
+		local atkPos = getPos(CombatDefine.ATTACK_SIDE, i)
+		local atkObj = CombatImpl.objList[atkPos]
+		if atkObj then
+			if atkObj.isSysAttrChange then
+                CombatObj.calcAttr(atkObj)
+				-- -- 重新计算血量
+				-- if combatType == CombatDefine.COMBAT_TYPE9 then
+				-- 	DrillLogic.calcAttrAtk(human, i, atkObj, cbParam)
+				-- elseif combatType == CombatDefine.COMBAT_TYPE17 then
+				-- 	ValleyLogic.calcAttr(CombatDefine.ATTACK_SIDE, i, atkObj, cbParam)
+				-- elseif combatType == CombatDefine.COMBAT_TYPE8 then
+				-- 	LianyuLogic.recalcHpFightBegin(human, i, atkObj)
+                -- end
+			end
+			atkObj.hpMax = CombatObj.getHpMax(atkObj)
+			atkObj.hp = atkObj.hp or CombatObj.getHpMax(atkObj)
+			atkObj.mp = atkObj.mp or atkObj.attr[RoleDefine.INIT_MP]
+			atkObj.initHp = atkObj.hp
+			atkObj.initMp = atkObj.mp
+		end		
+		local defPos = getPos(CombatDefine.DEFEND_SIDE, i)
+		local defObj = CombatImpl.objList[defPos]
+		if defObj then
+			if defObj.isSysAttrChange then
+                CombatObj.calcAttr(defObj)
+				-- if combatType == CombatDefine.COMBAT_TYPE9 then
+				-- 	DrillLogic.calcAttrDef(human, i, defObj, cbParam)
+				-- elseif combatType == CombatDefine.COMBAT_TYPE17 then
+				-- 	ValleyLogic.calcAttr(CombatDefine.DEFEND_SIDE, i, defObj, cbParam)
+				-- end	
+			end
+			defObj.hpMax = CombatObj.getHpMax(defObj)
+			defObj.hp = defObj.hp or CombatObj.getHpMax(defObj)
+			defObj.mp = defObj.mp or defObj.attr[RoleDefine.INIT_MP]
+			defObj.initHp = defObj.hp
+			defObj.initMp = defObj.mp
+		end
+	end
+end
+
+
+local function onFightBegin(human, combatType, cbParam, param)
+	-- local moduleFn = getModule(combatType)
+	-- if moduleFn and moduleFn.onFightBegin then
+	-- 	moduleFn.onFightBegin(human, cbParam, combatType, param)
+	-- end
+	
+	BeSkill.onFightBegin()
+	-- SkinLogic.onFightBegin(human) -- 处理皮肤属性, 这里原来逻辑也有问题,先不处理
+	CombatPosLogic.onFightBegin(human)
+	recalcHpFightBegin(human, combatType, cbParam)
+	CombatLogic.ElfInheritHeroAttr()
+end
+
+
+
+function combatBegin(attackerInfo, defenderInfo, combatType, onFightEndFunc, extraArgs)
+    CombatImpl.init(combatType)
+    local mapID = getMapID(combatType)
+
+    if not attackerInfo or not next(attackerInfo) then
+        return
+    end
+
+    if not defenderInfo or not next(defenderInfo) then
+        return
+    end
+
+
+	local defender, defHelp = defenderInfo.objList, defenderInfo.helpList
+    local defRBase, defFormation, defJiban, defElfList = defenderInfo.roleBase, defenderInfo.formation, defenderInfo.jiBan, defenderInfo.elfList
+
+	local attacker, atkHelp = attackerInfo.objList, attackerInfo.helpList
+    local atkRBase, atkFormation, atkJiban, atkElfList = attackerInfo.roleBase, attackerInfo.formation, attackerInfo.jiBan,attackerInfo.elfList
+
+	if not (attacker and next(attacker)) then
+		return
+	end
+
+	if not defender or not next(defender) then
+		return
+	end
+
+
+	local human = {}
+
+    local combatInfo = initCombatInfo(human, combatType, mapID)
+    combatInfo.attacker = atkRBase or {}
+    combatInfo.atkHelp = atkHelp or {}
+    combatInfo.atkFormation = atkFormation
+    combatInfo.atkJiban = atkJiban
+    combatInfo.defender = defRBase or {}
+    combatInfo.defHelp = defHelp or {}
+    combatInfo.defFormation = defFormation
+	combatInfo.defJiban = defJiban
+	combatInfo.posAttr[CombatDefine.ATTACK_SIDE] = CombatPosLogic.getPosAttr(attacker)
+	combatInfo.posAttr[CombatDefine.DEFEND_SIDE] = CombatPosLogic.getPosAttr(defender)
+	combatInfo.jiban[CombatDefine.ATTACK_SIDE] = JibanLogic.getJiban(attacker,atkJiban)
+	combatInfo.jiban[CombatDefine.DEFEND_SIDE] = JibanLogic.getJiban(defender,defJiban) 
+	combatInfo.maxRound = getMaxRound(combatType)
+	combatInfo.fightMode = getFightMode(combatType)
+
+	JibanLogic.setBeSkill(attacker,combatInfo.jiban[CombatDefine.ATTACK_SIDE])
+	JibanLogic.setBeSkill(defender,combatInfo.jiban[CombatDefine.DEFEND_SIDE])
+
+	
+    local changePos = nil
+    -- if combatType == CombatDefine.COMBAT_TYPE10 then
+    --     for k,v in pairs(attacker) do
+    --         changePos = k
+    --         attacker[k] = nil
+    --         attacker[5] = v
+    --         break
+    --     end
+    -- end
+	setCombatInfo(atkFormation, attacker, CombatDefine.ATTACK_SIDE)
+	setCombatInfo(defFormation, defender, CombatDefine.DEFEND_SIDE)
+	setHelp(atkHelp, CombatDefine.ATTACK_SIDE)
+	setHelp(defHelp, CombatDefine.DEFEND_SIDE)
+	setElf(atkElfList, CombatDefine.ATTACK_SIDE)
+	setElf(defElfList, CombatDefine.DEFEND_SIDE)
+	CombatImpl.setMaxRound(combatInfo.maxRound)
+	CombatImpl.setFightMode(combatInfo.fightMode)
+
+
+	onFightBegin(human, combatType, nil, {}, {})
+
+	while CombatImpl.calcFrame() do end
+    copyToCombatInfo(combatInfo)
+
+    combatInfo.changePos = changePos
+	local result = combatInfo.isWin and CombatDefine.RESULT_WIN or CombatDefine.RESULT_FAIL
+
+    if onFightEndFunc then
+        onFightEndFunc(result, combatType, combatInfo, extraArgs)
+    end
+end

+ 53 - 3
script/module/combat/CombatObj.lua

@@ -10,6 +10,7 @@ local CombatImpl = require("combat.CombatImpl")
 
 objs	= objs or {} 		-- [pos]->obj
 helps	= helps or {}
+elfs 	= elfs or {}	-- 精灵
 
 
 side2AddTimes = {}
@@ -97,6 +98,29 @@ function initAfterStart()
 		help.extraCombatRecord = nil --战斗中额外统计的数据
 		help.isPet = help.helpType == 1
 	end
+
+	local elfPosStartVal = CombatDefine.COMBAT_HERO_ALL_CNT + CombatDefine.COMBAT_HELP_ALL_CNT
+	for pos = 1,CombatDefine.COMBAT_ELF_ALL_CNT do
+		local elfObj = {}
+		elfObj.attr = {}
+		RoleAttr.initCombatAttr(elfObj.attr)
+		-- elfObj.replaceAttr = {}	-- 把replaceAttr中值>0的属性替换到attr中
+		-- RoleAttr.initCombatAttr(elfObj.replaceAttr)
+		elfObj.helpType		= CombatDefine.HELP_TYPE2   -- 辅助对象类型 武将/魔兽
+		elfObj.pos = pos + elfPosStartVal
+		elfObj.id = nil
+		elfObj.head = 0
+		elfObj.body = 0
+		elfObj.quality = 0
+		elfObj.side = pos > CombatDefine.COMBAT_ELF_CNT and CombatDefine.DEFEND_SIDE or CombatDefine.ATTACK_SIDE
+		elfObj.skillList = nil
+		elfObj.beSkillList = nil
+		elfObj.result = {0,0,0,0}		--战斗中输出和治疗 承受伤害 出手回合数 汇总
+		elfObj.combatResult = {0,0,{},0,{}}	--每次攻击受到的伤害和治疗
+		elfObj.extraCombatRecord = nil --战斗中额外统计的数据
+		elfObj.isElf = true
+		elfs[elfObj.pos] = elfObj
+	end
 end
 
 function getObjByPos(pos)
@@ -197,6 +221,32 @@ function initHelp(help)
 	RoleAttr.initCombatAttr(help.attr) 	
 end
 
+function initElf(elfObj)
+	elfObj.id = nil
+	elfObj.skillList = nil
+	elfObj.beSkillList = nil
+
+	elfObj.quality = 0
+	elfObj.head = 0
+	elfObj.body = 0
+    elfObj.icon = 0
+	elfObj.result[1] = 0
+	elfObj.result[2] = 0
+	elfObj.result[3] = 0
+	elfObj.result[4] = 0
+	elfObj.combatResult[1] = 0
+	elfObj.combatResult[2] = 0
+	for k in pairs(elfObj.combatResult[3]) do
+		elfObj.combatResult[3][k] = nil 
+	end
+	for k in pairs(elfObj.combatResult[5]) do
+		elfObj.combatResult[5][k] = nil 
+	end
+	elfObj.extraCombatRecord = nil
+	RoleAttr.initCombatAttr(elfObj.attr)
+end
+
+
 function setInitAttr(obj, attr)
 	local initAttr = obj.initAttr
 	for key in pairs(initAttr) do
@@ -313,11 +363,11 @@ local function getDijianHurtRate(obj)
 end
 
 
-local function beforeUpdateHp(obj,sum)
+local function beforeUpdateHp(obj,sum, nAddNum, nDelHP)
    if BeSkill.beforeUpdateHp(obj,sum) then
    	  return
    end
-   if CombatBuff.beforeUpdateHp(obj,sum) then
+   if CombatBuff.beforeUpdateHp(obj,sum, nAddNum, nDelHP) then
    	  return
    end
 
@@ -402,7 +452,7 @@ function updateHp(obj, value,isRevive,delayCB, attackPos,type)
 	if sum < 0 then
 		sum = 0
 	end
-	local ret = beforeUpdateHp(obj,sum)
+	local ret = beforeUpdateHp(obj, sum, value, d)
 	if ret then
 		obj.hp = sum
 	end

+ 89 - 19
script/module/combat/CombatPosLogic.lua

@@ -49,7 +49,8 @@ local LostTempleCombatLogic = require("lostTemple.lostTempleCombatLogic")
 local RecommendLineup = require("drawCard.RecommendLineup")
 local TalismanLogic = require("talisman.TalismanLogic")
 local NewFirstChargeLogic = require("present.NewFirstChargeLogic")
-
+local ElfLogic = require("elf.ElfLogic")
+local Skill = require("combat.Skill")
 
 
 --秘宝的加成
@@ -165,13 +166,14 @@ local function checkUpdatePos(human, msg)
 
 	if msg.type == CombatDefine.COMBAT_TYPE25 or  msg.type == CombatDefine.COMBAT_TYPE26 or
 		msg.type == CombatDefine.COMBAT_TYPE27 or msg.type == CombatDefine.COMBAT_TYPE28 then
-			local moduleFn = CombatLogic.getModule(msg.type)
-			if moduleFn and moduleFn.checkUpdatePos then
-				if not moduleFn.checkUpdatePos(human, msg) then
-					return false
-				end
+
+		local moduleFn = CombatLogic.getModule(msg.type)
+		if moduleFn and moduleFn.checkUpdatePos then
+			if not moduleFn.checkUpdatePos(human, msg) then
+				return false
 			end
 		end
+	end
 
     local posList = getPosList(msg.formation)
     local heroList = Util.split(msg.heroList, ",")
@@ -632,33 +634,38 @@ function posQuery(human, combatType, group, param, flag)
 	-- 购买新首充所有礼包后, 所有战斗都可以第一回合跳过
 	local isAllQuick = NewFirstChargeLogic.IsBuyAllgift(human)
 
-
+	-- local moduleFn = CombatLogic.getModule(msg.type)
+	
 	if group and group ~= 0 then
 		for k,v in pairs(CombatExcel.combat) do
-			if v.group == group then
-				len = len + 1
-				msgRet.list[len].type = k
-				msgRet.list[len].name = v.name
-                -- msgRet.list[len].isQuickTime = v.isQuickTime
-				if isAllQuick then
-					msgRet.list[len].isQuickTime = v.isQuickTime2
-				else
-					msgRet.list[len].isQuickTime = newIsQuickTime and newIsQuickTime or v.isQuickTime
+			if v.group == group and v.nRoleID then
+				local bOpen = RoleSystemLogic.checkOpenByID(human, v.nRoleID)
+				
+				if true == bOpen then
+					len = len + 1
+					msgRet.list[len].type = k
+					msgRet.list[len].name = v.name
+					-- msgRet.list[len].isQuickTime = v.isQuickTime
+					if isAllQuick then
+						msgRet.list[len].isQuickTime = v.isQuickTime2
+					else
+						msgRet.list[len].isQuickTime = newIsQuickTime and newIsQuickTime or v.isQuickTime
+					end
+					msgRet.list[len].needLv = RoleSystemLogic.getOpenLv(v.systemID)
 				end
-				msgRet.list[len].needLv = RoleSystemLogic.getOpenLv(v.systemID)
 			end
 		end
 	else
 		len = len + 1
 		msgRet.list[len].type = combatType
 		msgRet.list[len].name = combatConfig.name
-        -- msgRet.list[len].isQuickTime = combatConfig.isQuickTime
+		-- msgRet.list[len].isQuickTime = combatConfig.isQuickTime
 		if isAllQuick then
 			msgRet.list[len].isQuickTime = combatConfig.isQuickTime2
 		else
 			msgRet.list[len].isQuickTime = newIsQuickTime and newIsQuickTime or combatConfig.isQuickTime
 		end
-        msgRet.list[len].needLv = RoleSystemLogic.getOpenLv(combatConfig.systemID)
+		msgRet.list[len].needLv = RoleSystemLogic.getOpenLv(combatConfig.systemID)
 	end
 	msgRet.type = combatType
     msgRet.teamType = combatConfig.teamType
@@ -720,6 +727,11 @@ function posQuery(human, combatType, group, param, flag)
     local skillConfig = SkillExcel.skill[skillID]
     msgRet.moshouSkill = skillConfig and skillConfig.icon or ""
 
+	msgRet.elfSystemState = 0
+	if ElfLogic.ModuleisOpen(human) then
+		msgRet.elfSystemState = 1
+	end
+
 	Msg.send(msgRet,human.fd)
 end
 
@@ -868,4 +880,62 @@ function updateZdl(human, uuidList)
       msgRet.list[0] = len
       Msg.send(msgRet,human.fd)
    end
+end
+
+
+
+----------------------精灵-------------------------
+
+-- 查询某个战斗类型的精灵上阵数据
+function Elf_Pos_Query(human, combatType)
+	local combatPosData = getCombatHeroDB(human,combatType)
+	local elfList = combatPosData.elfList
+
+	local msgRet = Msg.gc.GC_COMBAT_ELFPOS_QUERY
+	local msgElfPosArr = msgRet.elfPosArr
+	msgElfPosArr[0] = CombatDefine.COMBAT_ELF_NOW_CNT
+
+	for i=1, CombatDefine.COMBAT_ELF_NOW_CNT do
+		msgElfPosArr[i].elfId = 0
+		msgElfPosArr[i].nowSkillDesc = ""
+		msgElfPosArr[i].nowSkillIcon = ""
+
+		if elfList and elfList[i] then
+			local elfId = elfList[i]
+			local skillId = ElfLogic.GetElfSkill(human, elfId)
+			local skillConfig = Skill.GetSkillConfig(skillId)
+
+			if skillConfig then
+				msgElfPosArr[i].elfId = elfId
+				msgElfPosArr[i].nowSkillDesc = skillConfig.desc
+				msgElfPosArr[i].nowSkillIcon = skillConfig.icon
+			end
+		end
+	end
+
+	Msg.send(msgRet,human.fd)
+end
+
+-- 更新某个战斗类型的精灵上阵数据
+function Elf_Pos_Update(human, combatType, elfIdArr)
+	local combatPosData = getCombatHeroDB(human,combatType)
+
+	local ElfEecordTb = {}
+	for _ ,elfId in ipairs(elfIdArr) do
+		if elfId > 0 then
+			if not ElfLogic.IsActivateElf(human, elfId) then
+				return Broadcast.sendErr(human, Lang.ELF_NOT_ACTIVATE)
+			end
+
+			if ElfEecordTb[elfId] then
+				return Broadcast.sendErr(human, Lang.ELF_SANME_ERR)
+			end
+
+			ElfEecordTb[elfId] = true
+		end
+	end
+
+	combatPosData.elfList = elfIdArr
+
+	Elf_Pos_Query(human, combatType)
 end

+ 33 - 1
script/module/combat/CombatVideo.lua

@@ -17,6 +17,7 @@ local Broadcast = require("broadcast.Broadcast")
 local RoleLogic = require("role.RoleLogic")
 local InnerMsg = require("core.InnerMsg")
 local MiddleManager = require("middle.MiddleManager")
+local PanelDefine = require("broadcast.PanelDefine")
 
 
 VIDEO_SINGLE_MAXCNT = 5 	-- 个人记录条数上限
@@ -33,6 +34,7 @@ VIDEOTYPE_THRONE = 4 		-- 王者争霸
 VIDEOTYPE_BATTLE = 5 		-- 战役记录
 VIDEOTYPE_JJCLODDER = 6		-- 天梯赛
 VIDEOTYPE_GODSAREA = 7		-- 诸神圣域
+VIDEOTYPE_AREABATTLE = 8	-- 战区争霸
 
 --------------------------------------------- db ---------------------------------------------------
 local QueryByUuid = {_id = nil}
@@ -82,7 +84,7 @@ local COMBATVIDEO_LIST_CACHE = {}
 local FieldSimple = {["combatInfo.result"] = 0}
 function getCombatVideosByType(videoType, key)
 	QueryByType.videoType = videoType
-    if videoType == VIDEOTYPE_THRONE or videoType == VIDEOTYPE_GODSAREA then
+    if videoType == VIDEOTYPE_THRONE or videoType == VIDEOTYPE_GODSAREA or videoType == VIDEOTYPE_AREABATTLE then
         FieldSimple = {}
     end
 	QueryByType.key = key
@@ -332,6 +334,22 @@ function cleanJJCLadderVideo()
 	LuaMongo.remove(DB.db_combat_video, QueryByType)		
 end
 
+-- 保存战斗录像(无数量限制)
+function SaveCombatVideo(videoType, combatInfo, arg1, arg2)
+	createCombatVideo(videoType, combatInfo, arg1, arg2)
+end
+
+
+
+-- 清空某个类型的录像数据
+function ClearOutVideoByCombatType(combatType)
+	if not combatType then
+		return
+	end
+	local queryTb = {videoType = combatType}
+	LuaMongo.remove(DB.db_combat_video, queryTb)
+end
+
 ---------------------------------------------普通服处理------------------------------------------
 
 local function lookCSCombatVideo(combatVideo, args)
@@ -350,6 +368,18 @@ local function lookCSCombatVideo(combatVideo, args)
 	CombatLogic.sendCombatFinish(human, combatInfo)
 end
 
+local function videoPlayBack(combatVideo, args)
+	local human = ObjHuman.onlineUuid[args.playerUid]
+	if not human then
+		return
+	end
+	combatVideo.combatInfo.panelID = PanelDefine.PANEL_ID_1018
+	CombatLogic.repeatCombat(human, combatVideo.combatInfo)
+end
+
+
+
+
 -- 向跨服查询战斗录像数据
 function NS_Video_Query(videoUuid, extraArgs)
 	if not videoUuid then
@@ -374,6 +404,8 @@ function NS_Video_Query_Result(msg)
 
 	if extraArgs.opType == 1 then
 		lookCSCombatVideo(msg.videoData, extraArgs)
+	elseif extraArgs.opType == 2 then
+		videoPlayBack(msg.videoData, extraArgs)
 	end
 end
 

+ 11 - 0
script/module/combat/Handler.lua

@@ -97,4 +97,15 @@ end
 
 function CG_HERO_UPDATE_ZDL(human,msg)
 	CombatPosLogic.updateZdl(human,msg.uuid)
+end
+
+
+--------------------精灵---------------------------
+
+function CG_COMBAT_ELFPOS_QUERY(human,msg)
+	CombatPosLogic.Elf_Pos_Query(human, msg.combatType)
+end
+
+function CG_COMBAT_ELFPOS_DO(human,msg)
+	CombatPosLogic.Elf_Pos_Update(human, msg.combatType, msg.elfPosArr)
 end

+ 0 - 12
script/module/combat/JibanLogic.lua

@@ -120,7 +120,6 @@ function initAfterHot()
 end
 
 function query(human,combatType,heroID)
-	-- print("请求羁绊英雄数据================", combatType, heroID)
 	local flag = RoleSystemLogic.isOpen(human,RoleSystemDefine.ROLE_SYS_ID_207)
 	if flag ~= true then
 		return
@@ -167,9 +166,6 @@ function query(human,combatType,heroID)
 		HeroGrid.makeHeroSimple(net.hero, heroGrid, index)
 	end
 	msgRet.posList[0] = len
-
-
-	-- print("请求羁绊英雄数据结束================", msgRet.jibanList[0], msgRet.posList[0])
 	Msg.send(msgRet,human.fd)
 end
 
@@ -254,7 +250,6 @@ function getJiban(objList,jibanList)
 		local obj = objList[i]
         -- 不是玩家不计算羁绊
 		if obj and obj.type == CombatDefine.COMBAT_OBJ_TYPE1 then
-			-- print("上阵英雄ID================", obj.id)
 			objHero[obj.id] = objHero[obj.id] or 0
 			objHero[obj.id] = objHero[obj.id] + 1
 		end
@@ -323,7 +318,6 @@ end
 
 function getJibanHero(human,combatHeroDB)
 	local jibanHero = {}
-	-- print("开始获取羁绊英雄数据================", human.db.name, combatHeroDB.jiban and true or false)
 	if combatHeroDB.jiban then
 		-- for k, uuid in pairs(combatHeroDB.jiban) do
 		-- 	if uuid ~= "0" and uuid ~= "" then
@@ -340,7 +334,6 @@ function getJibanHero(human,combatHeroDB)
 		-- end
 
 		for k, uuid in pairs(combatHeroDB.jiban) do
-			-- print(string.format("===========羁绊英雄数据, 位置: %s, 英雄UUID: %s", k, uuid))
 			if uuid ~= "0" and uuid ~= "" then
 				local heroGrid = HeroLogic.getHeroGridByUuid(human, uuid)
 				if heroGrid then
@@ -367,10 +360,6 @@ function getJibanHero(human,combatHeroDB)
 				end
 			end
 		end
-
-		-- for k in pairs(jibanHero) do
-		-- 	print("筛选出的羁绊英雄================", k)
-		-- end
 	end
 	return jibanHero
 end
@@ -444,7 +433,6 @@ function setBeSkill(objList,jiban)
 end
 
 function update(human,combatType,jibanListStr)
-	-- print("更新羁绊英雄数据================", combatType,jibanListStr)
     local conf = CombatExcel.combat[combatType]
     if not conf then return end
 

+ 27 - 2
script/module/combat/Proto.lua

@@ -50,6 +50,7 @@ GC_COMBAT_POS_QUERY = {
     {"moshouLock",	1,	"byte"},          --魔兽开启
     {"moshouSkill",	1,	"string"},        --魔兽开启
     {"totalZdl",	1,	"int"},           --战斗力
+	{"elfSystemState",	1,	"byte"},      -- 精灵系统状态, 0 - 未解锁, 1 -  已解锁
 }
 
 POS_ATTR_DATA = {
@@ -203,7 +204,7 @@ GC_COMBAT_BEGIN = {
 	{"combatType",		1,		"byte"}, -- 战斗类型
 	{"keepTime",		1,		"short"},-- 服务端经过了多少时间
 	{"heros",			12,		CombatHeroNet}, 	-- 对战英雄信息(站位)
-	{"helps",			10,		CombatHelpNet}, 	-- 对战辅助对象信息(站位)
+	{"helps",			10,		CombatHelpNet}, 	-- 对战辅助对象信息(站位), 精灵数据也放这里, 目前两方辅助之和最多2个,两方精灵之和最多8个
 	{"mapID",			1,		"int"},				-- 战斗场景
 	{"skillList",		60,	    CombatSkillConf},	-- 战斗中使用过的技能
 	{"cmdList",			16,		CombatCmdConf},	    -- 战斗中使用过的作用
@@ -305,7 +306,7 @@ CombatFinishData = {
 	{"self",    	1,      RoleBase},
 	{"target",		1,		RoleBase},
 	{"items",		20,		ItemData},
-	{"result",		14,		CombatResultNet},
+	{"result",		22,		CombatResultNet},
 	{"param",		1,		"string"},
 	{"isVideo",		1,		"byte"},
 	{"lookType",	1,		"byte"},	--查看途径 0-原始 1-聊天 2-个人记录
@@ -441,4 +442,28 @@ CG_HERO_UPDATE_ZDL = {
 
 GC_HERO_UPDATE_ZDL = {
     {"list",	10,		CombatHeroZdl},
+}
+
+
+-----------------------------精灵布阵------------------------
+
+ELF_POS_INFO = {
+	{"elfId",			1,		"int"},      	-- 精灵Id
+	{"nowSkillDesc",	1,		"string"},  	-- 当前技能说明
+	{"nowSkillIcon",	1,		"string"},  		-- 当前技能Icon
+}
+
+
+-- 查询精灵布阵数据
+CG_COMBAT_ELFPOS_QUERY = {
+	{"combatType",			1,		"byte"},	--战斗类型
+}
+GC_COMBAT_ELFPOS_QUERY = {
+	{"elfPosArr",		4,		ELF_POS_INFO},	--阵容数据
+}
+
+-- 精灵布阵
+CG_COMBAT_ELFPOS_DO = {
+	{"combatType",			1,		"byte"},	-- 战斗类型
+	{"elfPosArr",			4,		"int"},		-- 数组, key对应位置, value为精灵Id,如果当前位置没有精灵上阵,value为0
 }

+ 87 - 2
script/module/combat/Skill.lua

@@ -224,6 +224,15 @@ local function realUse(obj, skillID, fanjiTargets,otherArgs)
 			end
 		end
 		BeSkill.onHit(obj,newTargets,skillID)
+
+		if fanjiTargets then
+			for _, v in ipairs(fanjiTargets) do
+				if true == CombatBuff.isLianjie1(v) then
+					CombatBuff.CombatBuff_handleLianjie(v, obj)
+				end
+			end
+		end
+
 		CombatImpl.totalAtkCnt = CombatImpl.totalAtkCnt + 1
 	end
 	CombatImpl.nowAttacker	= nil
@@ -943,13 +952,23 @@ end
 
 function CMD.fanji(obj,skillConfig,skillTargets)
 	if CombatImpl.isFanji or CombatImpl.comboType > 0 then return end
-	if CombatBuff.isStatus(obj,{"xuanyun","shihua","bingdong", "xuanyun2", "chenshui"}) then return end
+	if CombatBuff.isStatus(obj,{"xuanyun","shihua","bingdong", "xuanyun2", "chenshui", "donghe", "gandian"}) then return end
 	if obj.side == skillTargets[1].side then
 		return
 	end
 	if obj.hp > 0 then
 		local r = math.random(0,10000)
 		if r < skillConfig.args[2] then
+			for i=#skillTargets, 1, -1 do
+				if BeSkill.isNoFanji(skillTargets[i]) then
+					table.remove(skillTargets, i)
+				end
+			end
+
+			if #skillTargets == 0 then
+				return
+			end
+
 			CombatImpl.fanjiList[#CombatImpl.fanjiList + 1] = {obj,skillConfig.args[1],skillTargets}
 		end
 	end
@@ -1296,6 +1315,11 @@ function CMD.combo(obj,skillConfig,skillTargets)
     end
 
 	if CombatImpl.isFanji or CombatImpl.comboType > 0 then return end
+
+	-- if CombatImpl.isFanji or (CombatImpl.comboType > 0 and CombatImpl.comboType ~= 999) then
+	-- 	return
+	-- end
+
 	if GroupSkillCnt ~= 1 then return end--技能包首次技能攻击才能触发
 	local r = math.random(0,10000)
 	if r < skillConfig.args[1] then
@@ -1341,6 +1365,11 @@ function CMD.combo1(obj,skillConfig,skillTargets)
     end
 
 	if CombatImpl.isFanji or CombatImpl.comboType > 0 then return end
+	-- if CombatImpl.isFanji or (CombatImpl.comboType > 0 and CombatImpl.comboType ~= 999) then
+	-- 	return
+	-- end
+
+
 	if GroupSkillCnt ~= 1 then return end--技能包首次技能攻击才能触发
 	local r = math.random(0,10000)
 	if r < skillConfig.args[1] then
@@ -1363,6 +1392,10 @@ function CMD.combo2(obj,skillConfig,skillTargets)
     end
 
 	if CombatImpl.isFanji or CombatImpl.comboType > 0 then return end
+	-- if CombatImpl.isFanji or (CombatImpl.comboType > 0 and CombatImpl.comboType ~= 999) then
+	-- 	return
+	-- end
+
 	if GroupSkillCnt ~= 1 then return end--技能包首次技能攻击才能触发
 	local r = math.random(0,10000)
 	if r < skillConfig.args[1] then
@@ -1426,9 +1459,13 @@ function CMD.attrcomboAgain(obj, skillConfig, skillTargets)
 			return
 		end
 	end
- 
+
 	local nSkillID = tComboCof[3] or CombatImpl.getSkillID(obj)
 	if CombatImpl.isFanji or CombatImpl.comboType > 0 then return end
+	-- if CombatImpl.isFanji or (CombatImpl.comboType > 0 and CombatImpl.comboType ~= 999) then
+	-- 	return
+	-- end
+
 	if GroupSkillCnt ~= 1 then return end--技能包首次技能攻击才能触发
 	local r = math.random(0,10000)
 	--print("[CMD.attrcomboAgain] nSkillID = "..nSkillID)
@@ -1438,6 +1475,34 @@ function CMD.attrcomboAgain(obj, skillConfig, skillTargets)
 	end
 end
 
+
+function CMD.zhuiji(obj,skillConfig,skillTargets)
+    -- 二次元 屏蔽 治疗 复活的连击
+    if ProjectLogic.isSsecy() then
+		local argSkillID = skillConfig.args[3] or CombatImpl.getSkillID(obj)
+		if skillIsHpOrRevive(obj, argSkillID) then
+			return
+		end
+
+		if skillIsHpOrRevive(obj, skillConfig.id) then
+			return
+		end
+    end
+
+	local objTag = obj.uuid or obj.id
+	if CombatImpl.useZhuijiObjList[obj.pos] and (CombatImpl.useZhuijiObjList[obj.pos][objTag] or 0) >= 1 then
+		return
+	end
+
+	-- if CombatImpl.isFanji or CombatImpl.comboType > 0 then return end
+	if GroupSkillCnt ~= 1 then return end--技能包首次技能攻击才能触发
+	local r = math.random(0,10000)
+	if r < skillConfig.args[1] then
+		CombatImpl.comboList[#CombatImpl.comboList + 1] = {obj, 999, skillConfig.args[2], skillConfig.args[3],skillConfig.args[4] or 1, skillConfig.args[5]}
+		return true
+	end
+end
+
 function CMD.baohu(obj,skillConfig,skillTargets)
 	local d = CombatObj.updateHp(obj,obj.baohuHurt,nil,nil, obj.pos,CombatObj.BUFFER_HP_TYPE)
 	if d ~= 0 then
@@ -1480,6 +1545,26 @@ function CMD.zuzhouHurt(obj, skillConfig, skillTargets)
     obj.args = nil
 end
 
+-- 根据诅咒数增加伤害
+function CMD.zuzhouTrueHurt(obj, skillConfig, skillTargets)
+	local confArgs = skillConfig.args
+	local nAtt = CombatObj.getValue(obj,RoleDefine.ATK)
+	local nHurt = nAtt * confArgs[1] / 10000
+	for _,target in ipairs(skillTargets) do
+		local isStatus, cmd, ind = CombatBuff.isStatus(target, {"zuzhou"})
+		if isStatus then
+			local nZuZhouNum = #target.bufferCmd["zuzhou"]
+			nHurt = nHurt * nZuZhouNum
+			if nHurt > 0  then
+				local d = CombatObj.updateHp(target, -nHurt,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
+				if d ~= 0 then
+					CombatImpl.setExtraHit(target,-nHurt,CMD2ID["zuzhouTrueHurt"])
+					CombatObj.onHpCB(target,d, obj.pos)
+				end
+			end
+		end
+	end
+end
 
 function CMD.dnexhurt(obj,skillConfig,skillTargets)
     local args = obj.isPet and obj.args or skillConfig.args

+ 30 - 2
script/module/combat/TargetMode.lua

@@ -30,9 +30,34 @@ local function getTargetSide(attacker,targetMode)
 	end
 end
 
+local function CheckbuffCanChose(attacker, objTarget)
+	if not attacker or not objTarget then
+		return true
+	end
+
+	-- 同阵营可以选择
+	if objTarget.pos == attacker.pos then
+		return true
+	end
+
+	local bHaveTrueVision = CombatBuff.isStatus(attacker, {"truevision"})
+	local bHaveQianXing = CombatBuff.isStatus(objTarget, {"qianxing"})
+	-- 无真视
+	if not bHaveTrueVision then
+		if not bHaveQianXing then	-- 无潜行
+			return true
+		else						-- 有潜行不可选中
+			return false
+		end
+	else
+		return true
+	end
+end
 
 local function canTarget(obj)
-	if obj and obj.hp and  obj.hp > 0 and not CombatBuff.isStatus(obj,{"revive"}) and CombatDefine.isBackup(obj) ~= CombatDefine.BACKUP_TYPE1 then
+	if obj and obj.hp and  obj.hp > 0 
+		and not CombatBuff.isStatus(obj,{"revive"}) 
+		and CombatDefine.isBackup(obj) ~= CombatDefine.BACKUP_TYPE1  then
 		return true
 	end
 end
@@ -213,9 +238,12 @@ function getTargets(attacker, targetMode, skillTargets, cmdTargets, checkChaofen
 			handlerFenTan(attacker, targetMode, skillTargets, cmdTargets, skillID)
 		end
     end
+	
     local ret = { }
     for _, v in ipairs(targets) do
-		ret[#ret + 1] = v
+		if true == CheckbuffCanChose(attacker, v) then
+			ret[#ret + 1] = v
+		end
     end
     return ret
 end

+ 126 - 12
script/module/dailyTask/HonorJourney.lua

@@ -18,6 +18,7 @@ local CommonDefine = require("common.CommonDefine")
 local TriggerLogic = require("trigger.TriggerLogic")
 local TriggerDefine = require("trigger.TriggerDefine")
 local YjTreasureDBLogic = require("yjTreasure.YjTreasureDB")
+local HeroLogic = require("hero.HeroLogic")
 
 -- HonorJourney ={
 --  nPoint = 0,             -- 荣耀积分
@@ -232,6 +233,18 @@ local function HonorJourney_Gettaskpre(id)
 end
 
 local function HonorJourneyTask_CheckFinshTask(human)
+    -- 检查新加的任务
+    local tTaskPrize = human.db.HonorJourney.TaskPrize
+    for nID, v in pairs(HonorJourneyExcel.HonorJourney) do
+        if not tTaskPrize[nID] then
+            tTaskPrize[nID] = {
+                nFinishNum = 0,
+                nState = CommonDefine.COMMON_PRIZE_STATE_NOGET
+            }
+        end
+    end
+
+    -- 检测凤凰等级
     if human.db.moshou and human.db.moshou.lv then
         local nNowFengHuangLv = human.db.moshou.lv
         print("[HonorJourneyTask_CheckFinshTask] 当前凤凰等级 nNowFengHuangLv = "..nNowFengHuangLv)
@@ -272,16 +285,33 @@ local function HonorJourneyTask_CheckFinshTask(human)
         end
     end
 
-    -- 检查新加的任务
-    local tTaskPrize = human.db.HonorJourney.TaskPrize
+    -- 检查是否获得指定英雄
     for nID, v in pairs(HonorJourneyExcel.HonorJourney) do
-        if not tTaskPrize[nID] then
-            tTaskPrize[nID] = {
-                nFinishNum = 0,
-                nState = CommonDefine.COMMON_PRIZE_STATE_NOGET
-            }
+        if v.triggerType == TriggerDefine.EVENT_TYPE_GETPOINTHERO then
+            local nState = HonorJourney_GetTaskStatus(human,  nID)
+            if nState == CommonDefine.COMMON_PRIZE_STATE_NOGET then
+                local tTaskArgument = Util.split(v.taskArgument , "|")
+                if 2 == #tTaskArgument then
+                    local nHeroID, nHeroStar = tonumber(tTaskArgument[1]), tonumber(tTaskArgument[2])
+                    local tListHeroIndex = HeroLogic.getHeroListById(human, nHeroID)
+                    if nil ~= _G.next(tListHeroIndex) then
+                        for _, nIndex in ipairs(tListHeroIndex) do
+                            local tHeroGrid = HeroLogic.getHeroGrid(human, nHeroID, nIndex)
+                            if tHeroGrid.star and tHeroGrid.id then
+                                print("[HonorJourneyTask_CheckFinshTask] 检测获得指定英雄 nHeroID = "..nHeroID.." star = "..tHeroGrid.star)
+                                if tHeroGrid.star >= nHeroStar and tHeroGrid.id == nHeroID then
+                                    HonorJourneyTask_AddTaskFinishNum(human, nID, 1)
+                                    HonorJourney_CheckTaskStatus(human, nID)
+                                end
+                            end
+                        end
+                    end
+                    
+                end
+            end
         end
     end
+
 end
 
 function HonorJourneyTaskQuery(human, isOnLogin)
@@ -578,7 +608,6 @@ local function HonorJourney_EvnentGetHero(nEventType, uuid, nValue1, nValue2)
                 print("[HonorJourney_EvnentGetHero] 获得英雄但是没有获取到对应的配置参数要求")
             else
                 local tTaskArgument = Util.split(v.taskArgument , "|")
-                table.print_lua_table(tTaskArgument)
                 if 2 ~= #tTaskArgument then
                     print("[HonorJourneyTask_EvnentGetHero] 获取的任务 参数数量不正确")
                 else
@@ -810,6 +839,84 @@ local function HonorJourneyTask_JingjieLvChange(nEventType, uuid, nValue1, nValu
     end
 end
 
+-- 获得指定英雄
+local function HonorJourneyTask_EvnentGetPointHero(nEventType, uuid, nValue1, nValue2, nValue3)
+    local human = ObjHuman.onlineUuid[uuid]
+    if not human then
+        return
+    end
+
+    if not nValue1 or not nValue2 or not nValue3 then
+        return
+    end
+
+    local nNum, nStar, nHeroID = nValue1, nValue2, nValue3
+    local bCheck, nTaskID = false, 0
+
+    print("[HonorJourneyTask_EvnentGetPointHero] nEventType = "..nEventType.." nNum = "..nNum.." nStar = "..nStar.." nHeroID = "..nHeroID.." name = "..human.db.name)
+
+    for nID, v in pairs(HonorJourneyExcel.HonorJourney) do
+        if v.triggerType == nEventType then
+            if not v.taskArgument or v.taskArgument == "" then
+                print("[HonorJourneyTask_EvnentGetPointHero] 获得英雄但是没有获取到对应的配置参数要求")
+            else
+                local tTaskArgument = Util.split(v.taskArgument , "|")
+                local nHeroCofID, nHeroCofStar = tonumber(tTaskArgument[1]), tonumber(tTaskArgument[2])
+                
+                if nHeroID == nHeroCofID then
+                    print("[HonorJourneyTask_EvnentGetPointHero] 配置的英雄ID = "..nHeroCofID.." 星级 = "..nHeroCofStar)
+                    local nStatus = HonorJourney_GetTaskStatus(human, nID)
+                    if nStar >= nHeroCofStar and CommonDefine.COMMON_PRIZE_STATE_NOGET == nStatus then
+                        HonorJourneyTask_AddTaskFinishNum(human, nID, 1)
+                        bCheck = true
+                        nTaskID = nID
+                        break
+                    end
+                end
+            end
+        end
+    end
+
+    if true == bCheck then
+        HonorJourney_CheckTaskStatus(human, nTaskID)
+        RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_803)
+    end
+end
+
+local function HonorJourneyTask_EvnentGetJingLing(nEventType, uuid, nValue1, nValue2)
+     local human = ObjHuman.onlineUuid[uuid]
+    if not human then
+        return
+    end
+
+    if not nValue1 or not nValue2 then
+        return
+    end
+
+    local nNum = nValue1
+    local nJingLingID = nValue2
+    local bCheck, nTaskID = false, 0
+    
+    for nID, v in pairs(HonorJourneyExcel.HonorJourney) do
+        if v.triggerType == nEventType then
+            if v.taskArgument and v.taskArgument == nJingLingID then
+                local nStatus = HonorJourney_GetTaskStatus(human, nID)
+                if CommonDefine.COMMON_PRIZE_STATE_NOGET == nStatus then
+                    HonorJourneyTask_AddTaskFinishNum(human, nID, 1)
+                    bCheck = true
+                    nTaskID = nID
+                    break
+                end
+            end
+        end
+    end
+
+     if true == bCheck then
+        HonorJourney_CheckTaskStatus(human, nTaskID)
+        RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_803)
+    end
+end
+
 function Init()
     tEventHandler = {
         [TriggerDefine.CHAT_TIMES] = HonorJourneyTask_EvnentCommon,
@@ -843,13 +950,16 @@ function Init()
         [TriggerDefine.ZHONGZU_LEVEL] = HonorJourneyTask_ItemActivate,
         [TriggerDefine.MIBAO_ALLSTAR] = HonorJourneyTask_EvnentCommon,
         [TriggerDefine.YIWU_ALLSTAR] = HonorJourneyTask_EvnentCommon,
+        [TriggerDefine.EVENT_TYPE_GETPOINTHERO] = HonorJourneyTask_EvnentGetPointHero,
+        [TriggerDefine.EVENT_TYPE_JINGLING_GET] = HonorJourneyTask_EvnentGetJingLing,
+        [TriggerDefine.EVENT_TYPE_JINGLING_STAR] = HonorJourneyTask_EvnentCommon,
     }
 end
 
 --订阅事件
 
 local function HonorJourney_SubEvent(uuid, nEventType)
-    print("当前进入荣耀历程订阅事件 注册 nEventType = "..nEventType)
+    -- print("当前进入荣耀历程订阅事件 注册 nEventType = "..nEventType)
     TriggerLogic.SubscribeEvent(nEventType, uuid, HonorJourneyTask_EventCallBack)
 end
 
@@ -899,11 +1009,15 @@ local function HonorJourney_OnLoginSubEvent(human)
     HonorJourney_SubEvent(uuid, TriggerDefine.MIBAO_ALLSTAR)
     HonorJourney_SubEvent(uuid, TriggerDefine.YIWU_ALLSTAR)
 
-    
+    -- 获取指定英雄
+    HonorJourney_SubEvent(uuid, TriggerDefine.EVENT_TYPE_GETPOINTHERO)
+    HonorJourney_SubEvent(uuid, TriggerDefine.EVENT_TYPE_JINGLING_GET)
+
+    HonorJourney_SubEvent(uuid, TriggerDefine.EVENT_TYPE_JINGLING_STAR)
 end
 
 -- 回调,增加次数
-function HonorJourneyTask_EventCallBack(nEventType, uuid, nValue1, nValue2)
+function HonorJourneyTask_EventCallBack(nEventType, uuid, nValue1, nValue2, nValue3)
     if not tEventHandler then
         Init()
     end
@@ -914,7 +1028,7 @@ function HonorJourneyTask_EventCallBack(nEventType, uuid, nValue1, nValue2)
     end
 
     print("[HonorJourneyTask_EventCallBack] 触发事件回调 nEventType = "..nEventType.." nValue1 = "..nValue1)
-    pcall(tEventHandler[nEventType], nEventType, uuid, nValue1, nValue2)
+    pcall(tEventHandler[nEventType], nEventType, uuid, nValue1, nValue2, nValue3)
     print("[HonorJourneyTask_EventCallBack] 触发事件回调 处理结束 ")
 end
 

+ 3 - 0
script/module/drawCard/DrawCardLogic.lua

@@ -60,6 +60,7 @@ local TriggerLogic = require("trigger.TriggerLogic")
 local WeekTaskLogic = require("dailyTask.WeekTaskLogic")
 local ClutterDataLogic = require("clutter.ClutterDataLogic")
 local ClutterDataDefine = require("clutter.ClutterDataDefine")
+local WarOrder = require("shop.WarOrder")
 
 DRAWCARD_ID0 = 0	-- 积分召唤
 DRAWCARD_ID1 = 1	-- 基础召唤
@@ -774,6 +775,8 @@ local function draw(human, id, op, actConfig, skip,isAct)
 
         --高级召唤周任务
         WeekTaskLogic.recordWeekTaskFinishCnt(human, WeekTaskLogic.WEEK_TASK_ID_2, heroCnt)
+
+        WarOrder.trigger(human, 7, heroCnt) -- 招募战令
     end
 
     sendDrawOp(human, id, op, heroList, fenjielist, heroNewList,heroIndexList,isAct)

+ 17 - 0
script/module/drawCard/Handler.lua

@@ -1,5 +1,6 @@
 local DrawCardLogic = require("drawCard.DrawCardLogic")
 local RecommendLineup = require("drawCard.RecommendLineup")
+local UnlimitDrawLogic = require("drawCard.UnlimitDrawLogic")
 
 function CG_DRAWCARD_QUERY(human,msg)
 	DrawCardLogic.query(human)
@@ -19,4 +20,20 @@ end
 
 function CG_DRAWCARD_SKIP_HEROSHOW(human, msg)
 	DrawCardLogic.SetHeroSkip(human, msg.bOperate)
+end
+
+function CG_UNLIMITDRAW_QUERY(human, msg)
+	UnlimitDrawLogic.UnlimitDrawLogic_Query(human)
+end
+
+function CG_UNLIMITDRAW_DO(human, msg)
+	UnlimitDrawLogic.UnlimitDrawLogic_Do(human)
+end
+
+function CG_UNLIMITDRAW_ABANDON(human, msg)
+	UnlimitDrawLogic.UnlimitDrawLogic_Abandon(human)
+end
+
+function CG_UNLIMITDRAW_GET(human, msg)
+	UnlimitDrawLogic.UnlimitDrawLogic_Get(human)
 end

+ 24 - 1
script/module/drawCard/Proto.lua

@@ -71,4 +71,27 @@ CG_DRAWCARD_GET_RECOMMEND_LINEUP = {}
 GC_DRAWCARD_GET_RECOMMEND_LINEUP = {
 	{"bIsEnd",   1,		"byte"},		
 	{"list",  35, RecommendLineup}
-}
+}
+
+-- 获取无限高抽数据
+CG_UNLIMITDRAW_QUERY = {}
+
+-- 回复无限高抽数
+GC_UNLIMITDRAW_QUERY = {
+	{"nNowNum",		1,		"byte"},		-- 当前抽取次数
+	{"tGetInfo",	4,		"byte"},		-- 获得记录 1已获得,0 未获得
+}
+
+-- 进行抽取
+CG_UNLIMITDRAW_DO = {}
+
+-- 抽取回复
+GC_UNLIMITDRAW_DO = {
+	{"tHeros",			10,		HeroNiceNet},	-- 召唤获得英雄
+}
+
+-- 放弃
+CG_UNLIMITDRAW_ABANDON = {}
+
+-- 领取英雄
+CG_UNLIMITDRAW_GET = {}

+ 13 - 3
script/module/drawCard/RecommendLineup.lua

@@ -18,7 +18,7 @@ local tTuiJian = require("excel.tuijian")
 
 local nRecommendLineupLen = 30		 -- 阵容记录推荐数量
 local tRecommendLineupData = nil
-local nSendLen = 15                     -- 一次性发送数据长度
+local nSendLen = 10                     -- 一次性发送数据长度
 
 ---------------------------------------- 内部函数 ------------------------------------
 local function RecommendLineup_GetData()
@@ -188,14 +188,15 @@ function GetRecommendLineUp(human)
 
     local tMsgData = Msg.gc.GC_DRAWCARD_GET_RECOMMEND_LINEUP
     tMsgData.list[0] = 0 
-    tMsgData.bIsEnd = 1
 
+    local nAllLen, nNowSendLen = #tData, 0
     for _, v in ipairs(tData) do
         tMsgData.list[0] = tMsgData.list[0] + 1
         -- print("[GetRecommendLineUp] i = "..tMsgData.list[0])
         local tHeroData = tMsgData.list[tMsgData.list[0]]
         tHeroData.name = v.name
         tHeroData.data[0] = 0
+        nNowSendLen = nNowSendLen + 1
 
         for i, tHero in ipairs(v.list) do
             tHeroData.data[0] = tHeroData.data[0] + 1
@@ -207,10 +208,19 @@ function GetRecommendLineUp(human)
             tHeroSimple.star = nHeroStar
             -- print("[GetRecommendLineUp] 封装 英雄数据结束 nHeroID = "..nHeroID.." nHeroStar = "..nHeroStar.." i = "..i)
         end
+
+        if tMsgData.list[0] >= nSendLen then
+            tMsgData.bIsEnd = nNowSendLen == nAllLen and 1 or 0
+            Msg.send(tMsgData, human.fd)
+            tMsgData.list[0] = 0
+        end
         -- table.print_lua_table(tHeroData)
     end
 	
-    Msg.send(tMsgData, human.fd)
+    if tMsgData.list[0] > 0 then
+        tMsgData.bIsEnd = 1
+        Msg.send(tMsgData, human.fd)
+    end
 	print("[GetRecommendLineUp] 发送成功 ")
 end
 

+ 301 - 0
script/module/drawCard/UnlimitDrawLogic.lua

@@ -0,0 +1,301 @@
+--------------------------------
+-- 文件名       :  UnlimitDrawLogic.lua
+-- 文件说明     :  无限高抽
+-- 创建时间     :   2025/09/29
+-- 创建人       :   FC
+--------------------------------
+local Util = require("common.Util")
+local Lang = require("common.Lang")
+local Msg = require("core.Msg")
+local Grid = require("bag.Grid")
+local HeroGrid = require("hero.HeroGrid")
+local HeroLogic = require("hero.HeroLogic")
+local BagLogic = require("bag.BagLogic")
+local Log = require("common.Log")
+local Broadcast = require("broadcast.Broadcast")
+local DrawCardExcel = require("excel.drawCard").drawCard
+local RandomLogic = require("common.RandomLogic")
+local HeroDefine = require("hero.HeroDefine")
+local HeroExcel = require("excel.hero").hero
+local HeroBook = require("hero.HeroBook")
+local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
+local RoleSystemDefine = require("roleSystem.RoleSystemDefine")
+
+-- local DrawCardLogic = require("drawCard.DrawCardLogic")
+
+local UNLIMIT_CARD_ID = 12
+local UNLIMIT_CARD_LV = 35
+
+----------------------------------------- 内部处理开始 -------------------------------------
+local function UnlimitDraw_CreateDB(human)
+    human.db.UnlimitDraw = {
+        nNowNum = 0,
+        bLogin = false,
+        bLv = false,
+        nFirstLoginTime = 0,
+        bNextLogin = false,
+        tChacheHero = nil,
+    }
+end
+
+local function UnlimitDraw_CheckDB(human)
+    if not human.db.UnlimitDraw then
+        UnlimitDraw_CreateDB(human)
+    end
+end
+
+local function UnlimitDraw_GetNum(human)
+    return human.db.UnlimitDraw.nNowNum
+end
+
+local function UnlimitDraw_SetNum(human, nValue)
+    human.db.UnlimitDraw.nNowNum = human.db.UnlimitDraw.nNowNum + nValue
+    if human.db.UnlimitDraw.nNowNum < 0 then
+        human.db.UnlimitDraw.nNowNum = 0
+    end
+end
+
+local function UnlimitDraw_GetLogin(human)
+    return human.db.UnlimitDraw.bLogin
+end
+
+local function UnlimitDraw_SetLogin(human, bValue)
+    human.db.UnlimitDraw.bLogin = bValue
+end
+
+local function UnlimitDraw_GetLoginTime(human)
+    return human.db.UnlimitDraw.nFirstLoginTime
+end
+
+local function UnlimitDraw_SetLoginTime(human, nValue)
+    human.db.UnlimitDraw.nFirstLoginTime = nValue
+end
+
+local function UnlimitDraw_GetLv(human)
+    return human.db.UnlimitDraw.bLv
+end
+
+local function UnlimitDraw_SetLv(human, bValue)
+    human.db.UnlimitDraw.bLv = bValue
+end
+
+local function UnlimitDraw_GetNextLogin(human)
+    return human.db.UnlimitDraw.bNextLogin
+end
+
+local function UnlimitDraw_SetNextLogin(human, bValue)
+    human.db.UnlimitDraw.bNextLogin = bValue
+end
+
+local function UnlimitDraw_SetCacheHero(human, tHeroInfo)
+    human.db.UnlimitDraw.tChacheHero = tHeroInfo
+end
+
+local function UnlimitDraw_GetCacheHero(human)
+    return human.db.UnlimitDraw.tChacheHero
+end
+
+local function UnlimitDraw_ClearCacheHero(human)
+    human.db.UnlimitDraw.tChacheHero = nil
+end
+
+local function UnlimitDraw_randHeroID(human, config, randomIndex)
+    local heroID = nil
+    local rindex = RandomLogic.getRandom1(config.weight, nil, 2)
+    local rconf = config.weight[rindex]
+    local weightLv = rconf[1]
+
+    heroID = heroID or HeroDefine.getRandHeroByWeightLv(weightLv)
+    return heroID
+end
+
+
+----------------------------------------- 客户端请求 -------------------------------------
+function UnlimitDrawLogic_Query(human)
+    UnlimitDraw_CheckDB(human)
+
+    local tMsgData = Msg.gc.GC_UNLIMITDRAW_QUERY
+
+    tMsgData.nNowNum = UnlimitDraw_GetNum(human)
+    tMsgData.tGetInfo[0] = 3
+    tMsgData.tGetInfo[1] = UnlimitDraw_GetLogin(human) and 1 or 0
+    tMsgData.tGetInfo[2] = UnlimitDraw_GetLv(human) and 1 or 0
+    tMsgData.tGetInfo[3] = UnlimitDraw_GetNextLogin(human) and 1 or 0
+
+    Msg.send(tMsgData, human.fd)
+end
+
+function UnlimitDrawLogic_Do(human)
+    local nNowNum = UnlimitDraw_GetNum(human)
+    if 0 >= nNowNum then
+        return
+    end
+
+    local nDoNum = 10
+    local config = DrawCardExcel[UNLIMIT_CARD_ID]
+
+    if HeroLogic.getEmptyCnt(human) < nDoNum then
+        return Broadcast.sendErr(human, Lang.HERO_BAG_FULL)
+    end
+
+    UnlimitDraw_ClearCacheHero(human)
+
+    local heroLen = 0
+    local heroList = {}
+    local heroNewList = {}
+    local heroIndexList = {}
+    local fenjielist = {}
+    local heroIDs = nil
+
+    local randomMin = math.random(1, nDoNum)
+    for i = 1, nDoNum, 1 do
+        local nHeroID = UnlimitDraw_randHeroID(human, config, randomMin)
+        if nHeroID then
+            local heroConfig = HeroExcel[nHeroID]
+            local star = heroConfig.star
+            local name = heroConfig.name
+            local grade = heroConfig.grade
+            local isNew = not HeroBook.isGet(human, heroConfig.id, heroConfig.star)
+            -- local heroIndex, fjlist = HeroLogic.addHero(human, nHeroID, nil, 1, "draw_card")
+
+            heroLen = heroLen + 1
+            heroList[heroLen] = nHeroID
+            heroNewList[heroLen] = isNew
+
+            if not heroIDs then
+                heroIDs = nHeroID
+            else
+                heroIDs = heroIDs .. "|" .. nHeroID
+            end
+        else
+            print("[UnlimitDrawLogic_Do] 生成英雄失败直接返回")
+            return
+        end
+    end
+
+    local tMsgData = Msg.gc.GC_UNLIMITDRAW_DO
+    tMsgData.tHeros[0] = nDoNum
+    for i = 1, heroLen do
+        local heroID = heroList[i]
+        local isNew = heroNewList and heroNewList[i]
+        -- local index = heroIndexList and heroIndexList[i]
+        HeroGrid.makeHeroNice(tMsgData.tHeros[i], heroID, 1, isNew)
+    end
+
+    UnlimitDraw_SetCacheHero(human, heroList)
+    Msg.send(tMsgData, human.fd)
+end
+
+function UnlimitDrawLogic_Abandon(human)
+    UnlimitDraw_ClearCacheHero(human)
+end
+
+function UnlimitDrawLogic_Get(human)
+    local tHeroInfo = UnlimitDraw_GetCacheHero(human)
+    if not tHeroInfo then
+        return
+    end
+
+    local nNowNum = UnlimitDraw_GetNum(human)
+    if 0 >= nNowNum then
+        return
+    end
+
+    UnlimitDraw_SetNum(human, -1)
+
+    local heroIndexList = {}
+    local fenjielist = {}
+    for _, nID in ipairs(tHeroInfo) do
+        local heroIndex, fjlist = HeroLogic.addHero(human, nID,nil, 1, "UnlimitDrawCard")
+        if fjlist and type(fjlist) == "table" then
+            for fjItemID, fjItemCnt in pairs(fjlist) do
+                fenjielist[fjItemID] = (fenjielist[fjItemID] or 0) + fjItemCnt
+            end
+        end
+
+        table.insert(heroIndexList, heroIndex)
+    end
+
+    if nil ~= _G.next(fenjielist) then
+        local tItem = {}
+        for key, value in pairs(fenjielist) do
+            table.insert(tItem, {key, value})
+        end
+        BagLogic.sendItemGetList(human, tItem, "UnlimitDrawCard")
+    end
+    
+    UnlimitDraw_ClearCacheHero(human)
+    UnlimitDrawLogic_Query(human)
+    RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_111, nil, true)
+end
+
+function onLogin(human)
+    UnlimitDraw_CheckDB(human)
+
+    local bSendDot = false
+    local bLogin = UnlimitDraw_GetLogin(human)
+    if false == bLogin then
+        UnlimitDraw_SetLogin(human, true)
+        UnlimitDraw_SetLoginTime(human, os.time())
+        UnlimitDraw_SetNum(human, 1)
+        bSendDot = true
+    else
+        local nLastTime = UnlimitDraw_GetLoginTime(human)
+        local bNextLogin = UnlimitDraw_GetNextLogin(human)
+        if not Util.isSameDay(nLastTime) and false == bNextLogin then
+            UnlimitDraw_SetNextLogin(human, true)
+            UnlimitDraw_SetNum(human, 1)
+            bSendDot = true
+        end
+    end
+
+    local bLv = UnlimitDraw_GetLv(human)
+    if false == bLv and human.db.lv >= UNLIMIT_CARD_LV then
+        UnlimitDraw_SetLv(human, true)
+        UnlimitDraw_SetNum(human, 1)
+        bSendDot = true
+    end
+
+    if true == bSendDot then
+        RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_111)
+    end
+end
+
+function onLvUp(human, nNewLv)
+    local bLv = UnlimitDraw_GetLv(human)
+    if false == bLv and nNewLv >= UNLIMIT_CARD_LV then
+        UnlimitDraw_SetLv(human, true)
+        UnlimitDraw_SetNum(human, 1)
+        RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_111, true)
+    end
+end
+
+function ModuleisOpen(human)
+    UnlimitDraw_CheckDB(human)
+
+    if true == UnlimitDraw_GetLogin(human) and UnlimitDraw_GetLv(human) == true 
+        and true == UnlimitDraw_GetNextLogin(human) then
+        if UnlimitDraw_GetNum(human) > 0 then
+            return true
+        else
+            print("[ModuleisOpen] 当前系统未开放")
+            return false
+        end
+    end
+
+    return true
+end
+
+function isDot(human)
+    UnlimitDraw_CheckDB(human)
+
+    if true == ModuleisOpen(human) then
+        if UnlimitDraw_GetNum(human) > 0 then
+            local nNowNum = UnlimitDraw_GetNum(human)
+            print("[UnlimitDraw_isDot] 当前系统开放可抽取数量大于0 nNowNum = "..nNowNum)
+            return true
+        end
+    end
+
+    return false
+end

+ 5 - 2
script/module/drill/DrillDB.lua

@@ -37,7 +37,7 @@ end
 
 -- (本服)创建玩家对战信息
 function createDrillData(human, drillId)
-	local heroList, helpList, rolebase , formation, jiban = CombatLogic.getHumanObjList(human, CombatDefine.COMBAT_TYPE1)
+	local heroList, helpList, rolebase , formation, jiban, elfList = CombatLogic.getHumanObjList(human, CombatDefine.COMBAT_TYPE1)
 	if not heroList or not next(heroList) then return end -- 没有上阵
 
 	local drillData = {}
@@ -47,6 +47,7 @@ function createDrillData(human, drillId)
 	drillData.drillObjs = {} 			-- 关卡对象列表[drillId] = drillObj	
 	drillData.heroList = heroList
 	drillData.helpList = helpList
+	drillData.elfList = elfList
     drillData.jiban = jiban
 	drillData.formation = formation
 	drillData.heroStatus = nil			-- 英雄状态 [heroUuid] = hpRate
@@ -110,6 +111,7 @@ function createDrillMonster(uuid, monsterOutID, zhandouli)
 	drillObj.svrName = Config.SVR_NAME
 	drillObj.heroList = heroList
 	drillObj.helpList = helpList
+	drillObj.elfList = elfList
 	drillObj.formation = formation
 	drillObj.monsterOutID = monsterOutID 			-- 怪物额外字段
 	drillObj.objStatus = nil						-- 英雄状态 [index] = hpRate
@@ -143,7 +145,7 @@ function createDrillObj(uuid)
 	local fakeHuman = CombatLogic.createCombatFakeHuman(uuid)
 	if not fakeHuman then return end
 
-	local objList, helpList, rolebase, formation, jiban = CombatLogic.getHumanObjList(fakeHuman, CombatDefine.COMBAT_TYPE1)
+	local objList, helpList, rolebase, formation, jiban, elfList = CombatLogic.getHumanObjList(fakeHuman, CombatDefine.COMBAT_TYPE1)
 	if not objList or not next(objList) then return end -- 没有上阵
 
 	local drillObj = {}
@@ -152,6 +154,7 @@ function createDrillObj(uuid)
 	drillObj.uuid = nil
 	drillObj.heroList = objList
 	drillObj.helpList = helpList
+	drillObj.elfList = elfList
 	drillObj.formation = formation
 	drillObj.jiban = jiban
 	drillObj.objStatus = nil						-- 英雄状态 [index] = hpRate

+ 6 - 6
script/module/drill/DrillLogic.lua

@@ -770,7 +770,7 @@ end
 --检测是否有竞技场阵容
 --加入数据推送至中心服 [g->m]
 function onJjcPos(human)	
-	local heroList, helpList, rolebase , formation = CombatLogic.getHumanObjList(human, CombatDefine.COMBAT_TYPE3)
+	local heroList, helpList, rolebase , formation, elfList = CombatLogic.getHumanObjList(human, CombatDefine.COMBAT_TYPE3)
 	if not heroList or not next(heroList) then return end -- 没有上阵
 	
 	local drillObj = DrillDB.createDrillObj(human)
@@ -1240,7 +1240,7 @@ function getDefender(drillObj)
 	end	
 	local roleBase = {}
 	RoleLogic.makeRoleBase(drillObj, roleBase)
-	return objList, drillObj.helpList,  roleBase, drillObj.formation, drillObj.jiban
+	return objList, drillObj.helpList,  roleBase, drillObj.formation, drillObj.jiban, drillObj.elfList
 end
 
 -- 攻击方数据
@@ -1248,7 +1248,7 @@ function getAttacker(human, drillData, pos2uuidAtk)
 	local drill = human.db.drill
 	if not drill then return end
 
-	local objList, helpList, rolebase, formation, jiban = CombatLogic.getHumanObjList(human, CombatDefine.COMBAT_TYPE9)
+	local objList, helpList, rolebase, formation, jiban, elfList = CombatLogic.getHumanObjList(human, CombatDefine.COMBAT_TYPE9)
 	for pos, obj in pairs(objList) do
 		local heroGrid = human.db.heroBag[obj.bagIndex] 
 		if heroGrid then
@@ -1270,7 +1270,7 @@ function getAttacker(human, drillData, pos2uuidAtk)
 			end
 		end		
 	end
-	return objList, helpList, rolebase, formation, jiban
+	return objList, helpList, rolebase, formation, jiban, elfList
 end
 
 -------------------------------------- combat -----------------------------------------
@@ -1376,8 +1376,8 @@ function fight(human, args)
 	updateCombatPosCheck(human, drillData)
 	local args = {}
 	local pos2uuidAtk = {}
-	args.defender, args.defHelp, args.defRBase, args.defFormation, args.defJiban = getDefender(drillObj)
-	args.attacker, args.atkHelp, args.atkRBase, args.atkFormation, args.atkJiban = getAttacker(human, drillData, pos2uuidAtk)
+	args.defender, args.defHelp, args.defRBase, args.defFormation, args.defJiban, args.defElfList = getDefender(drillObj)
+	args.attacker, args.atkHelp, args.atkRBase, args.atkFormation, args.atkJiban, args.atkElfList = getAttacker(human, drillData, pos2uuidAtk)
     args.drillId = drillData.drillId
  
 

+ 623 - 0
script/module/elf/ElfLogic.lua

@@ -0,0 +1,623 @@
+-- 精灵系统
+
+--db
+--[=[
+    human.db.elfData = {
+        [elfId1] = {
+            level = 0,
+            star = 0,
+        },
+        [elfId2] = {
+            level = 0,
+            star = 0,
+        },
+    }
+
+]=]--
+
+local Msg = require("core.Msg")
+local Lang = require("common.Lang")
+local Broadcast = require("broadcast.Broadcast")
+local ElfConfig = require("excel.elf")
+local ItemConfig = require("excel.item").item
+local Grid = require("bag.Grid")
+local BagLogic = require("bag.BagLogic")
+local Skill = require("combat.Skill")
+local RoleAttr = require("role.RoleAttr")
+local RoleDefine = require("role.RoleDefine")
+local ObjHuman = require("core.ObjHuman")
+local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
+local RoleSystemDefine = require("roleSystem.RoleSystemDefine")
+-- local HuanJingTowerLogic = require("huanjingTower.HuanjingTowerLogic")
+local TalismanLogic = require("talisman.TalismanLogic")
+local TriggerLogic = require("trigger.TriggerLogic")
+local TriggerDefine = require("trigger.TriggerDefine")
+local ChengjiuLogic = require("chengjiu.ChengjiuLogic")
+
+local ELF_UPGRADELV_LOG_TAG = "elfUpGradeLv"
+local ELF_UPGRADESTAR_LOG_TAG = "elfUpGradeStar"
+-- local ELF_COND_TOWER_LEVEL =  600
+local ELF_2_CHENGJIU_TASKID = 406 -- 精灵系统对应的成就任务Id
+
+
+local function initElfData(human)
+    human.db.elfData = {}
+end
+
+local function getElfData(human)
+    return human.db.elfData
+end
+
+local function updateElfData(human, elfId, newLevel, newStar)
+    local elfData = getElfData(human)
+    if not elfData then
+        initElfData(human)
+        elfData = getElfData(human)
+    end
+
+    elfData[elfId] = elfData[elfId] or {level = 0, star = 0}
+
+    if newLevel then
+        elfData[elfId].level = newLevel
+    end
+
+    if newStar then
+        elfData[elfId].star = newStar
+    end
+end
+
+-- 获取来自秘宝的属性倍数加成
+local function getAttrMulFromTalisman(human)
+    local attrMul = TalismanLogic.getTalismanAdd(human, TalismanLogic.OTHER_EFFECT_TBL.Elf_Attr_Mul)
+    attrMul = attrMul / 100
+    return attrMul
+end
+
+local function getNextStarCostCnt(nextStar)
+    for _, starCfg in ipairs(ElfConfig.UpGradeStar) do
+        if nextStar == starCfg.star then
+            return starCfg.itemCnt
+        end
+    end
+
+    return 0
+end
+
+local function generateCfgByQuality(targetQuality)
+    local tbl = {}
+    for id, cfg in ipairs(ElfConfig.Elf) do
+        if cfg.elfQuality == targetQuality then
+            tbl[id] = cfg
+        end
+    end
+
+    if not next(tbl) then
+        return nil
+    end
+
+    return tbl
+end
+
+local function getElfCfgById(targetElfId)
+    for _, elfCfg in ipairs(ElfConfig.Elf) do
+        if elfCfg.elfId == targetElfId then
+            return elfCfg
+        end
+    end
+end
+
+
+
+-- 计算一共可以升多少级, 消耗多少道具
+local function calcUpGrade(nowLv, itemAllCnt, maxLv)
+    local addLv, oldItemAllCnt, itemCostCnt = 0, itemAllCnt, 0
+    while true do
+        nowLv = nowLv + 1
+        if nowLv > maxLv then
+            break
+        end
+
+        itemCostCnt = nowLv * 3 + 2
+        if itemAllCnt < itemCostCnt then
+            break
+        end
+
+        addLv = addLv + 1
+        itemAllCnt = itemAllCnt - itemCostCnt
+    end
+
+    local useItemCnt = oldItemAllCnt - itemAllCnt
+
+    return addLv, useItemCnt
+end
+-- 计算当前所有精灵的总星级
+local function calcAllElfStar(elfDataList)
+    local stars = 0
+    for _, elfData in pairs(elfDataList) do
+        stars = stars + elfData.star
+    end
+
+    return stars
+end
+-- 计算精灵当前等级加成属性之和
+local function calcLvAttr(elfLv, attrCfg)
+    local nowAttrVal = 0
+    for i=1, elfLv do
+        nowAttrVal = nowAttrVal + attrCfg[1] * i + attrCfg[2]
+    end
+    return nowAttrVal
+end
+
+
+
+local function populateMsgSimpleData(net, elfCfg, itemCfg, elfData)
+    if not net or not elfCfg or not itemCfg then
+        return
+    end
+
+    local elfNowLv = elfData and elfData.level or 0
+    local elfNowStar = elfData and elfData.star or 0
+
+    net.elfId = elfCfg.elfId
+    net.elfName = itemCfg.name
+    net.elfIcon = itemCfg.icon
+    net.elfLv = elfNowLv
+    net.elfStar = elfNowStar
+    net.elfQuality = elfCfg.elfQuality
+    net.maxLv = elfCfg.elfMaxLv
+    net.maxStar = elfCfg.elfMaxStar
+
+    local upGradeLvItemId = elfCfg.upGradeLvItemId
+    local upGradeLvItemCnt = elfNowLv >= elfCfg.elfMaxLv and 0 or (elfNowLv + 1) * 3 + 2
+    Grid.makeItem(net.elfUpGradeLvCost, upGradeLvItemId, upGradeLvItemCnt)
+
+    local upGradeStarItemId = elfCfg.upGradeStarItemId
+    local upGradeStarItemCnt = elfNowStar >= elfCfg.elfMaxStar and 0 or getNextStarCostCnt(elfNowStar+1)
+    Grid.makeItem(net.elfUpGradeStarCost, upGradeStarItemId, upGradeStarItemCnt)
+end
+
+local function populateMsgAttr(attrNet, attrCfg, attrId, elfLv, isMax, attrMul)
+    local sumAttrVal = calcLvAttr(elfLv, attrCfg)
+    attrNet.nowAttr.key = attrId
+    attrNet.nowAttr.value = sumAttrVal * (1 + attrMul)
+    attrNet.addAtrr.key = attrId
+    attrNet.addAtrr.value = (attrCfg[1] * (elfLv + 1) + attrCfg[2]) * (1 + attrMul)
+    if isMax then
+        attrNet.addAtrr.value = 0
+    end
+end
+
+local function populateMsgAttr2(attrNet, attrId, attrVal, elfStar, isMax, attrMul)
+    attrMul = 1 + attrMul
+
+    attrNet.nowAttr.key = attrId
+    attrNet.nowAttr.value = attrVal * elfStar * attrMul
+    attrNet.addAtrr.key = attrId
+    attrNet.addAtrr.value = attrVal
+    if isMax then
+        attrNet.addAtrr.value = 0
+    end
+end
+
+
+
+
+--是否开启本系统
+local function isOpen(human)
+    -- local towerLevel = HuanJingTowerLogic.getTowerLevel(human)
+    -- if towerLevel >= ELF_COND_TOWER_LEVEL then
+    --     return true
+    -- end
+    -- return false
+    local state = ChengjiuLogic.GetTaskState(human, ELF_2_CHENGJIU_TASKID)
+    if state == 2 then
+        return true
+    end
+
+    return false
+end
+-- 重算战力
+local function updatePower(human)
+    RoleAttr.cleanHeroAttrCache(human)
+    RoleAttr.doCalc(human)
+    ObjHuman.sendAttr(human, RoleDefine.ZHANDOULI)
+end
+--红点判断
+local function dotJudgment(human, cfgHtbl)
+    local elfData = getElfData(human)
+    for _, cfg in pairs(cfgHtbl) do
+        local nowLevel, nowStar = 0, 0
+        if elfData and elfData[cfg.elfId] then
+            nowLevel = elfData[cfg.elfId].level
+            nowStar = elfData[cfg.elfId].star
+        end
+
+        if nowStar < cfg.elfMaxStar then
+            local upGradeStarCostCnt = getNextStarCostCnt(nowStar+1)
+            if BagLogic.getItemCnt(human, cfg.upGradeStarItemId) >= upGradeStarCostCnt then
+                return true
+            end
+        end
+
+        -- 需要精灵可激活或已激活
+        if nowStar >= 1 and nowLevel < cfg.elfMaxLv then
+            nowLevel = nowLevel + 1
+            local costItemCnt = nowLevel * 3 + 2
+            if BagLogic.getItemCnt(human, cfg.upGradeLvItemId) >= costItemCnt then
+                return true
+            end
+        end
+    end
+
+    return false
+end
+-- 红点更新
+local function updateDot(human, targetQuality)
+    local cfgHtbl = generateCfgByQuality(targetQuality)
+
+    -- 该品质的所有精灵不能升星和升级了
+    if not dotJudgment(human, cfgHtbl) then
+        local dotID = 0
+        if targetQuality == 1 then
+            dotID = RoleSystemDefine.ROLE_SYS_ID_2032
+        elseif targetQuality == 2 then
+            dotID = RoleSystemDefine.ROLE_SYS_ID_2033
+        elseif targetQuality == 3 then
+            dotID = RoleSystemDefine.ROLE_SYS_ID_2034
+        else
+            dotID = RoleSystemDefine.ROLE_SYS_ID_2035
+        end
+
+        --刷新单页
+        RoleSystemLogic.onDot(human, dotID)
+        --刷新入口处
+        RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_2031)
+    end
+end
+
+
+
+-- 外部调用,精灵加成
+function doCalcHero(human, addAttrs)
+    if not human or not human.db then
+        return
+    end
+
+    local elfData = getElfData(human)
+    if not elfData then
+        return
+    end
+
+    local attrMul = getAttrMulFromTalisman(human)
+    attrMul = 1 + attrMul
+
+    for elfId, singleElfData in pairs(elfData) do
+        local elfCfg = getElfCfgById(elfId)
+        if elfCfg then
+            -- 等级加成
+            if singleElfData.level > 0 then
+                local atkVal = calcLvAttr(singleElfData.level, elfCfg.nAttack1)
+                local hpVal = calcLvAttr(singleElfData.level, elfCfg.nLife1)
+                RoleAttr.updateValue(RoleDefine.ATK, atkVal * attrMul, addAttrs)
+                RoleAttr.updateValue(RoleDefine.HP, hpVal * attrMul, addAttrs)
+            end
+
+            -- 星级加成
+            RoleAttr.updateValue(RoleDefine.ATK, elfCfg.nAttack2 * singleElfData.star * attrMul, addAttrs)
+            RoleAttr.updateValue(RoleDefine.HP, elfCfg.nLife2 * singleElfData.star * attrMul, addAttrs)
+            RoleAttr.updateValue(RoleDefine.DEF, elfCfg.nDefense2 * singleElfData.star * attrMul, addAttrs)
+            RoleAttr.updateValue(RoleDefine.SPEED, elfCfg.nSpeed2 * singleElfData.star * attrMul, addAttrs)
+        end
+
+    end
+end
+
+-- 外部调用, 本系统是否开启
+function ModuleisOpen(human)
+    return isOpen(human)
+end
+
+-- 外部调用, 是否有红点
+function isDot(human, dotConfig)
+    if not isOpen(human) then
+        return false
+    end
+    --入口处的红点判断
+    if dotConfig.id == RoleSystemDefine.ROLE_SYS_ID_2031 then
+        return dotJudgment(human, ElfConfig.Elf)
+    else
+        --单个分页的红点
+        local elfQuality = 0
+        if dotConfig.id == RoleSystemDefine.ROLE_SYS_ID_2032 then
+            elfQuality = 1
+        elseif dotConfig.id == RoleSystemDefine.ROLE_SYS_ID_2033 then
+            elfQuality = 2
+        elseif dotConfig.id == RoleSystemDefine.ROLE_SYS_ID_2034 then
+            elfQuality = 3
+        else
+            elfQuality = 4
+        end
+
+        local cfgHtbl = generateCfgByQuality(elfQuality)
+        if not cfgHtbl then
+            return false
+        end
+
+        return dotJudgment(human, cfgHtbl)
+    end
+end
+
+-- 外部调用,是否激活了精灵
+function IsActivateElf(human, elfId)
+    if not isOpen(human) then
+        return false
+    end
+
+    local elfData = getElfData(human)
+    if not elfData or not elfData[elfId] then
+        return false
+    end
+
+    return true
+end
+
+-- 外部调用,获取精灵当前技能
+function GetElfSkill(human, elfId)
+    -- if not isOpen(human) then
+    --     return
+    -- end
+
+    local elfData = getElfData(human)
+    if not elfData or not elfData[elfId] then
+        return
+    end
+
+    local elfNowStar = elfData[elfId].star
+    local elfCfg = getElfCfgById(elfId)
+    if not elfCfg then
+        return
+    end
+
+    return elfCfg.skillArr[elfNowStar]
+end
+
+
+
+
+-- 请求某个品质的所有精灵的简单数据
+function Elf_SimpleData_Query(human, targetElfQuality)
+    if not isOpen(human) then
+        return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED)
+    end
+
+    local elfData = getElfData(human) or {}
+    local msgRet = Msg.gc.GC_ELF_SIMPLEDATA_QUERY
+    local elfArr = msgRet.elfArr
+    elfArr[0] = 0
+    local len = 0
+    msgRet.allStars = calcAllElfStar(elfData)
+
+    for _, elfCfg in ipairs(ElfConfig.Elf) do
+        if elfCfg.elfQuality == targetElfQuality then
+            local elfId = elfCfg.elfId
+            local itemCfg = ItemConfig[elfId]
+            if itemCfg then
+                len = len + 1
+                populateMsgSimpleData(elfArr[len], elfCfg, itemCfg, elfData[elfId])
+            end
+        end
+    end
+
+    elfArr[0] = len
+    Msg.send(msgRet, human.fd)
+end
+
+-- 请求某个精灵的详细数据
+function Elf_SingleElf_Query(human, elfId)
+    if not isOpen(human) then
+        return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED)
+    end
+
+    local itemCfg = ItemConfig[elfId]
+    local elfCfg = getElfCfgById(elfId)
+    if not itemCfg or not elfCfg then
+        return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
+    end
+
+    local elfData = getElfData(human) or {}
+    local targetElfData = elfData[elfId]
+    local msgRet = Msg.gc.GC_ELF_SINGLE_QUERY
+
+    populateMsgSimpleData(msgRet.elfSimpleData, elfCfg, itemCfg, targetElfData)
+
+    local elfNowLv = targetElfData and targetElfData.level or 0
+    local elfNowStar = targetElfData and targetElfData.star or 0
+
+    local isMaxLv, isMaxStar = false, false
+    if elfNowLv >= elfCfg.elfMaxLv then
+        isMaxLv = true
+    end
+
+    if elfNowStar >= elfCfg.elfMaxStar then
+        isMaxStar = true
+    end
+
+    local elfSkillDataMsg = msgRet.elfSkillData
+
+    elfSkillDataMsg.nowSkillDesc = ""
+    local elfNowSkillId = elfCfg.skillArr[elfNowStar]
+    local nowSkillCfg = Skill.GetSkillConfig(elfNowSkillId)
+    if nowSkillCfg then
+        elfSkillDataMsg.nowSkillDesc = nowSkillCfg.desc
+    end
+
+    elfSkillDataMsg.nextSkillDesc = ""
+    local elfNextSkillId = isMaxStar and elfCfg.skillArr[#elfCfg.skillArr] or elfCfg.skillArr[elfNowStar+1]
+    local nextSkillCfg = Skill.GetSkillConfig(elfNextSkillId)
+    if nextSkillCfg then
+        elfSkillDataMsg.nextSkillDesc = nextSkillCfg.desc
+    end
+
+    elfSkillDataMsg.maxSkillDesc = ""
+    local elfMaxSkillId = elfCfg.skillArr[#elfCfg.skillArr]
+    local maxSkillCfg = Skill.GetSkillConfig(elfMaxSkillId)
+    if maxSkillCfg then
+        elfSkillDataMsg.maxSkillDesc = maxSkillCfg.desc
+    end
+
+    local attrMul = getAttrMulFromTalisman(human)
+
+    msgRet.elfLvAttrInfo[0] = 2
+    populateMsgAttr(msgRet.elfLvAttrInfo[1], elfCfg.nAttack1, RoleDefine.ATK, elfNowLv, isMaxLv, attrMul)
+    populateMsgAttr(msgRet.elfLvAttrInfo[2], elfCfg.nLife1, RoleDefine.HP, elfNowLv, isMaxLv, attrMul)
+
+    msgRet.elfStarAttrInfo[0] = 4
+    populateMsgAttr2(msgRet.elfStarAttrInfo[1], RoleDefine.HP, elfCfg.nLife2, elfNowStar, isMaxStar, attrMul)
+    populateMsgAttr2(msgRet.elfStarAttrInfo[2], RoleDefine.ATK, elfCfg.nAttack2, elfNowStar, isMaxStar, attrMul)
+    populateMsgAttr2(msgRet.elfStarAttrInfo[3], RoleDefine.DEF, elfCfg.nDefense2, elfNowStar, isMaxStar, attrMul)
+    populateMsgAttr2(msgRet.elfStarAttrInfo[4], RoleDefine.SPEED, elfCfg.nSpeed2, elfNowStar, isMaxStar, attrMul)
+
+    Msg.send(msgRet, human.fd)
+end
+
+-- 精灵升级
+function Elf_UpGradeLv(human, elfId, opType)
+    if not isOpen(human) then
+        return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED)
+    end
+
+    local elfCfg = getElfCfgById(elfId)
+    if not elfCfg then
+        return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
+    end
+
+    local elfData = getElfData(human) or {}
+
+    if not elfData[elfId] then
+        return Broadcast.sendErr(human, Lang.ELF_NOT_ACTIVATE)
+    end
+
+    local elfNowLv = elfData[elfId].level or 0
+    if elfNowLv >= elfCfg.elfMaxLv then
+        return Broadcast.sendErr(human, Lang.COMMON_MAXLEVEL)
+    end
+
+    local upGradeLvItemId = elfCfg.upGradeLvItemId
+    local upGradeLvItemCnt = 0
+    local itemAllCnt = BagLogic.getItemCnt(human, upGradeLvItemId)
+    if itemAllCnt <= 0 then
+        return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
+    end
+
+    -- if BagLogic.getItemCnt(human, upGradeLvItemId) < upGradeLvItemCnt then
+    --     return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
+    -- end
+
+    local addLv = 0
+    if opType == 1 then
+        addLv = 1
+        upGradeLvItemCnt = (elfNowLv + 1) * 3 + 2
+    elseif opType == 2 then
+        addLv, upGradeLvItemCnt = calcUpGrade(elfNowLv, itemAllCnt, elfCfg.elfMaxLv)
+    else
+        return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
+    end
+
+    if addLv == 0 or BagLogic.getItemCnt(human, upGradeLvItemId) < upGradeLvItemCnt then
+        return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
+    end
+
+    BagLogic.delItem(human, upGradeLvItemId, upGradeLvItemCnt, ELF_UPGRADELV_LOG_TAG)
+
+    updateElfData(human, elfId, elfNowLv+addLv)
+
+    Elf_SingleElf_Query(human, elfId)
+
+    updatePower(human)
+
+    -- 红点刷新
+    updateDot(human, elfCfg.elfQuality)
+end
+
+-- 精灵升星
+function Elf_UpGradeStar(human, elfId)
+    if not isOpen(human) then
+        return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED)
+    end
+
+    local elfCfg = getElfCfgById(elfId)
+    if not elfCfg then
+        return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
+    end
+
+    local elfData = getElfData(human) or {}
+    local elfNowStar = elfData[elfId] and elfData[elfId].star or 0
+    if elfNowStar >= elfCfg.elfMaxStar then
+        return Broadcast.sendErr(human, Lang.COMMON_MAXLEVEL)
+    end
+
+    local nextStar = elfNowStar+1
+    local upGradeStarItemId = elfCfg.upGradeStarItemId
+    local upGradeStarItemCnt = getNextStarCostCnt(nextStar)
+    if upGradeStarItemCnt == 0 then
+        return Broadcast.sendErr(human, Lang.ELF_MAX_STAR)
+    end
+
+    if BagLogic.getItemCnt(human, upGradeStarItemId) < upGradeStarItemCnt then
+        return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
+    end
+    BagLogic.delItem(human, upGradeStarItemId, upGradeStarItemCnt, ELF_UPGRADESTAR_LOG_TAG)
+
+    updateElfData(human, elfId, nil, nextStar)
+
+    Elf_SingleElf_Query(human, elfId)
+
+    updatePower(human)
+
+    -- 红点刷新
+    updateDot(human, elfCfg.elfQuality)
+
+    local nAllStar = calcAllElfStar(elfData)
+    TriggerLogic.PublishEvent(TriggerDefine.EVENT_TYPE_JINGLING_STAR, human.db._id, 1)
+end
+
+-- 布阵界面, 请求精灵数据
+function Elf_GetElfData_FromPosPage(human, targetElfQuality)
+    local msgRet = Msg.gc.GC_ELF_POS_QUERY
+    local elfArr = msgRet.elfArr
+    elfArr[0] = 0
+    local len = 0
+    local elfData = getElfData(human) or {}
+
+    for _, elfCfg in ipairs(ElfConfig.Elf) do
+        if elfCfg.elfQuality == targetElfQuality then
+            local elfId = elfCfg.elfId
+            local itemCfg = ItemConfig[elfId]
+            if itemCfg then
+                len = len + 1
+                local elfNowLv = elfData and elfData.level or 0
+                local elfNowStar = elfData[elfId] and elfData[elfId].star or 0
+
+                elfArr[len].elfId = elfId
+                elfArr[len].elfName = itemCfg.name
+                elfArr[len].elfIcon = itemCfg.icon
+                elfArr[len].elfLv = elfNowLv
+                elfArr[len].elfStar = elfNowStar
+                elfArr[len].elfQuality = targetElfQuality
+                elfArr[len].nowSkillDesc = ""
+                elfArr[len].nowSkillIcon = ""
+                
+                local elfNowSkillId = elfCfg.skillArr[elfNowStar]
+                local nowSkillCfg = Skill.GetSkillConfig(elfNowSkillId)
+                if nowSkillCfg then
+                    elfArr[len].nowSkillDesc = nowSkillCfg.desc
+                    elfArr[len].nowSkillIcon = nowSkillCfg.icon
+                end
+            end
+        end
+
+    end
+
+    elfArr[0] = len
+    Msg.send(msgRet, human.fd)
+end

+ 24 - 0
script/module/elf/Handler.lua

@@ -0,0 +1,24 @@
+local elfLogic = require("elf.ElfLogic")
+
+-- 请求某个品质的所有精灵的简单数据
+function CG_ELF_SIMPLEDATA_QUERY(human,msg)
+	elfLogic.Elf_SimpleData_Query(human, msg.elfQuality)
+end
+
+
+function CG_ELF_SINGLE_QUERY(human,msg)
+	elfLogic.Elf_SingleElf_Query(human, msg.elfId)
+end
+
+
+function CG_ELF_UPGRADE_LV(human,msg)
+	elfLogic.Elf_UpGradeLv(human, msg.elfId, msg.opType)
+end
+
+function CG_ELF_UPGRADE_STAR(human,msg)
+	elfLogic.Elf_UpGradeStar(human, msg.elfId)
+end
+
+function CG_ELF_POS_QUERY(human,msg)
+	elfLogic.Elf_GetElfData_FromPosPage(human, msg.elfQuality)
+end

+ 92 - 0
script/module/elf/Proto.lua

@@ -0,0 +1,92 @@
+local Attr = require("role.Proto").Attr
+local ItemData = require("bag.Proto").ItemData
+
+ELF_SIMPLE_INFO = {
+	{"elfId",			1,		"int"},      	-- 精灵Id
+    {"elfName",			1,		"string"},    	-- 精灵名字
+    {"elfIcon",			1,		"int"},    		-- 精灵Icon
+	{"elfLv",			1,		"int"},    		-- 精灵等级
+	{"elfStar",			1,		"int"},    		-- 精灵星级
+	{"elfQuality",		1,		"byte"},    	-- 精灵品质
+	{"elfUpGradeLvCost",	1,		ItemData},  -- 精灵升级消耗
+	{"elfUpGradeStarCost",	1,		ItemData},  -- 精灵升星消耗
+	{"maxLv",				1,		"int"},		-- 精灵最大等级
+	{"maxStar",				1,		"int"},		-- 精灵最高星数
+}
+
+
+--精灵技能数据
+ELF_SKILL_INFO = {
+	{"nowSkillDesc",			1,		"string"},  -- 当前技能说明
+	{"nextSkillDesc",			1,		"string"},  -- 当前技能说明
+	{"maxSkillDesc",			1,		"string"},  -- 当前技能说明
+}
+
+
+-- 精灵属性数据
+ELF_ATTR_INFO = {
+	{"nowAttr",			1,		Attr},      	-- 当前属性
+	{"addAtrr",			1,		Attr},      	-- 升级增加属性
+}
+
+
+
+-- 布阵界面的精灵数据
+ELF_POSPAGE_INFO = {
+	{"elfId",			1,		"int"},      	-- 精灵Id
+    {"elfName",			1,		"string"},    	-- 精灵名字
+    {"elfIcon",			1,		"int"},    		-- 精灵Icon
+	{"elfLv",			1,		"int"},    		-- 精灵等级
+	{"elfStar",			1,		"int"},    		-- 精灵星级
+	{"elfQuality",		1,		"byte"},    	-- 精灵品质
+	{"nowSkillDesc",	1,		"string"},  	-- 当前技能说明
+	{"nowSkillIcon",	1,		"string"},  		-- 当前技能Icon
+}
+
+
+
+
+
+-- 查询某个品质所有精灵的简单信息
+CG_ELF_SIMPLEDATA_QUERY = {
+	{"elfQuality",		1,		"byte"},	-- 精灵品质, 1-稀有, 2-史诗, 3-传说, 4-神话
+}
+GC_ELF_SIMPLEDATA_QUERY = {
+	{"elfArr",			20,		ELF_SIMPLE_INFO},
+	{"allStars",		1,		"short"},	-- 总星数
+}
+
+
+
+-- 查询某个精灵的详细信息
+CG_ELF_SINGLE_QUERY = {
+	{"elfId",			1,		"int"},      	-- 精灵Id
+}
+GC_ELF_SINGLE_QUERY = {
+	{"elfSimpleData",		1,		ELF_SIMPLE_INFO},   -- 精灵基础数据
+	{"elfSkillData",		1,		ELF_SKILL_INFO},    -- 精灵技能数据
+	{"elfLvAttrInfo",		2,		ELF_ATTR_INFO}, 	-- 精灵升级加成属性
+	{"elfStarAttrInfo",		4,		ELF_ATTR_INFO},  	-- 精灵升星加成属性
+}
+
+-- 精灵升级
+CG_ELF_UPGRADE_LV = {
+	{"elfId",			1,		"int"},      	-- 精灵Id
+	{"opType",			1,		"byte"},      	-- 升级方式, 1-升一级, 2-一键
+}
+
+
+-- 精灵升星
+CG_ELF_UPGRADE_STAR = {
+	{"elfId",			1,		"int"},      	-- 精灵Id
+}
+
+
+
+-- 布阵界面, 查询所有精灵数据
+CG_ELF_POS_QUERY = {
+	{"elfQuality",		1,		"byte"},	-- 精灵品质, 1-稀有, 2-史诗, 3-传说, 4-神话
+}
+GC_ELF_POS_QUERY = {
+	{"elfArr",			20,		ELF_POSPAGE_INFO},
+}

+ 2 - 2
script/module/equip/EquipLogic.lua

@@ -213,7 +213,7 @@ local function getIndexByRand(totalWeight, randList)
 end
 
 -- 随机出戒指、护符的特效
-local function randEffectAttrList(equipId)
+function randEffectAttrList(equipId)
     local equipCfg = EquipExcel[equipId]
 
     if equipCfg.subType ~= ItemDefine.EQUIP_SUBTYPE_RING and equipCfg.subType ~= ItemDefine.EQUIP_SUBTYPE_AMULET then
@@ -255,7 +255,7 @@ end
 ---------------------------------------------------------戒指、护符随机英雄专属---------------------------------------------------
 
 
-local function randHeroExclusive(equipId)
+function randHeroExclusive(equipId)
     local equipCfg = EquipExcel[equipId]
 
     if equipCfg.subType ~= ItemDefine.EQUIP_SUBTYPE_RING and equipCfg.subType ~= ItemDefine.EQUIP_SUBTYPE_AMULET then

+ 251 - 0
script/module/equip/EquipWash.lua

@@ -2,6 +2,7 @@
 local Msg = require("core.Msg")
 local EquipExcel = require("excel.equip").equip
 local EquipRareExcel = require("excel.equip").rare
+local EquipTeXiao = require("excel.equip").texiao
 local ItemDefine = require("bag.ItemDefine")
 local Grid = require("bag.Grid")
 local EquipLogic = require("equip.EquipLogic")
@@ -15,7 +16,14 @@ local HeroGrowUp = require("absAct.HeroGrowUp")
 local ObjHuman = require("core.ObjHuman")
 local TriggerLogic = require("trigger.TriggerLogic")
 local TriggerDefine = require("trigger.TriggerDefine")
+local HeroExcel = require("excel.hero")
+local HeroEquip = require("hero.HeroEquip")
 
+local EQUIPREFINING_EFFECT = 1  -- 效果
+local EQUIPREFINING_HERONAME = 2    -- 英雄名
+local EQUIPEFINING_DEL_GOODID = 183  -- 消耗的物品ID
+local EQUIPEFINING_DEL_TYPE_1 = 5   -- 重置效果消耗
+local EQUIPEFINING_DEL_TYPE_2 = 1   -- 重置英雄名消耗
 
 -- 取出合适的装备
 local function getEquipGrid(human, bagIndex, heroUuid, pos)
@@ -406,4 +414,247 @@ function CancelEquipRandomAttr(human, bagIndex, heroUuid, pos)
     equipGrid.washQuality = nil
 
     randomQuery(human, bagIndex, heroUuid, pos)
+end
+
+local function EquipRefining_GetData(equipGrid, tMsgData)
+     local baseRate = 1
+    --装备特效
+    local effectLen = 0
+    local msgEffects = tMsgData.tLefteffects
+    for effectId in pairs(equipGrid.effectList or {}) do
+        effectLen = effectLen + 1
+        local effectCfg = EquipTeXiao[effectId]
+
+        msgEffects[effectLen].name = effectCfg.name
+        msgEffects[effectLen].color = effectCfg.quality
+        msgEffects[effectLen].attr.key = effectCfg.attrs[1][1]
+        msgEffects[effectLen].attr.value = effectCfg.attrs[1][2]
+    end
+    msgEffects[0] = effectLen
+
+    -- 英雄专属
+    if equipGrid.exclusiveHeroId then
+        local heroCfg = HeroExcel.hero[equipGrid.exclusiveHeroId]
+        tMsgData.tLeftHero = heroCfg.name
+    end
+    
+    if equipGrid.RefiningEffectList then
+        effectLen = 0
+        local tData = tMsgData.tRighteffects
+        for effectId in pairs(equipGrid.RefiningEffectList) do
+            effectLen = effectLen + 1
+            local effectCfg = EquipTeXiao[effectId]
+
+            tData[effectLen].name = effectCfg.name
+            tData[effectLen].color = effectCfg.quality
+            tData[effectLen].attr.key = effectCfg.attrs[1][1]
+            tData[effectLen].attr.value = effectCfg.attrs[1][2]
+        end
+        tData[0] = effectLen
+    end
+
+    if equipGrid.RefiningHeroId then
+        local heroCfg = HeroExcel.hero[equipGrid.RefiningHeroId]
+        tMsgData.tRightHero = heroCfg.name
+    end
+end
+
+local function EquipRefining_CheckCanDo(id)
+    local itemConfig = ItemDefine.getConfig(id)
+    if not itemConfig then
+        return false
+    end
+
+    if itemConfig.subType ~= ItemDefine.EQUIP_SUBTYPE_RING and itemConfig.subType ~= ItemDefine.EQUIP_SUBTYPE_AMULET then
+        return false
+    end
+
+    return true
+end
+
+local function EquipRefining_CheckEffect(tNowEffect, tGetEffect)
+    local bRet = false
+
+    if nil == _G.next(tGetEffect) and nil ~= _G.next(tNowEffect)  then
+        return true
+    end
+
+    if nil ~= _G.next(tGetEffect) and nil == _G.next(tNowEffect) then
+        return true
+    end
+
+    for effectId in pairs(tGetEffect) do
+        if not tNowEffect[effectId] then
+            bRet = true
+            break
+        end
+    end
+
+    return bRet
+end
+
+local function EquipRefining_CheckHeroID(nNowHeroID, nGetHeroID)
+    local bRet = false
+    if nNowHeroID then
+        if not nGetHeroID then
+            bRet = true
+        else
+            if nNowHeroID ~= nGetHeroID then
+                bRet = true
+            end
+        end
+    else
+        if nGetHeroID then
+            bRet = true
+        end
+    end
+
+    return bRet
+end
+
+-- 装备精炼查询
+function EquipRefiningQuery(human, bagIndex, heroUuid, pos)
+    local equipGrid = getEquipGrid(human, bagIndex, heroUuid, pos)
+    if not equipGrid then
+        return Broadcast.sendErr(human, Lang.EQUIP_GRID_ERR)
+    end
+
+    if false == EquipRefining_CheckCanDo(equipGrid.id) then
+        return 
+    end
+
+    local tMsgData = Msg.gc.GC_EQUIP_REFINING_QUERY
+
+    tMsgData.tLefteffects[0] = 0
+    tMsgData.tLeftHero = ""
+    tMsgData.tRighteffects[0] = 0
+    tMsgData.tRightHero = ""
+
+    Grid.makeItem(tMsgData.tEffectItem, EQUIPEFINING_DEL_GOODID, EQUIPEFINING_DEL_TYPE_1)
+    Grid.makeItem(tMsgData.tHeroItem, EQUIPEFINING_DEL_GOODID, EQUIPEFINING_DEL_TYPE_2)
+
+    EquipRefining_GetData(equipGrid, tMsgData)
+	
+    Msg.send(tMsgData, human.fd)
+end
+
+-- 开始装备精炼
+function EquipRefiningDo(human, bagIndex, heroUuid, pos, nOperate)
+    local equipGrid = getEquipGrid(human, bagIndex, heroUuid, pos)
+    if not equipGrid then
+        return Broadcast.sendErr(human, Lang.EQUIP_GRID_ERR)
+    end
+
+    if false == EquipRefining_CheckCanDo(equipGrid.id) then
+        return 
+    end
+
+    local nNeedNum = nOperate == EQUIPREFINING_EFFECT and EQUIPEFINING_DEL_TYPE_1 
+        or (nOperate == EQUIPREFINING_HERONAME and EQUIPEFINING_DEL_TYPE_2 or (EQUIPEFINING_DEL_TYPE_1 + EQUIPEFINING_DEL_TYPE_2))
+
+    local nowItemCnt = BagLogic.getItemCnt(human, EQUIPEFINING_DEL_GOODID)
+    if nowItemCnt < nNeedNum then 
+        return Broadcast.sendErr(human, Util.format(Lang.XIANZHI_NO_ITEM, ItemDefine.getValue(EQUIPEFINING_DEL_GOODID,"name")))
+    end
+
+    BagLogic.delItem(human, EQUIPEFINING_DEL_GOODID, nNeedNum, "equip_wash")
+
+    local tNowEffect = {}
+    if equipGrid.effectList then
+        for effectId in pairs (equipGrid.effectList) do
+            tNowEffect[effectId] = 1
+        end
+    end
+
+    if nOperate == EQUIPREFINING_EFFECT then
+        for i = 1, 15, 1 do
+            equipGrid.RefiningEffectList = EquipLogic.randEffectAttrList(equipGrid.id)
+            if true == EquipRefining_CheckEffect(tNowEffect, equipGrid.RefiningEffectList) then
+                break
+            end
+        end
+    elseif EQUIPREFINING_HERONAME == nOperate then
+        for i = 1, 15, 1 do
+            equipGrid.RefiningHeroId = EquipLogic.randHeroExclusive(equipGrid.id)
+            if true == EquipRefining_CheckHeroID(equipGrid.exclusiveHeroId, equipGrid.RefiningHeroId) then
+                break
+            end
+        end
+    else
+        for i = 1, 15, 1 do
+            equipGrid.RefiningEffectList = EquipLogic.randEffectAttrList(equipGrid.id)
+            equipGrid.RefiningHeroId = EquipLogic.randHeroExclusive(equipGrid.id)
+            if true == EquipRefining_CheckEffect(tNowEffect, equipGrid.RefiningEffectList) and 
+                true == EquipRefining_CheckHeroID(equipGrid.exclusiveHeroId, equipGrid.RefiningHeroId) then
+                break
+            end
+        end
+    end
+
+    local tMsgData = Msg.gc.GC_EQUIP_REFINING_DO
+    tMsgData.tLeftHero = ""
+    tMsgData.tRightHero = ""
+    tMsgData.tLefteffects[0] = 0
+    tMsgData.tRighteffects[0] = 0
+    EquipRefining_GetData(equipGrid, tMsgData)
+
+    Msg.send(tMsgData, human.fd)
+end
+
+-- 放弃精炼
+function EquipRefiningAbandon(human, bagIndex, heroUuid, pos)
+    local equipGrid = getEquipGrid(human, bagIndex, heroUuid, pos)
+    if not equipGrid then
+        return Broadcast.sendErr(human, Lang.EQUIP_GRID_ERR)
+    end
+
+    if false == EquipRefining_CheckCanDo(equipGrid.id) then
+        return 
+    end
+
+    if equipGrid.RefiningEffectList then
+        equipGrid.RefiningEffectList = nil
+    end
+
+    if equipGrid.RefiningHeroId then
+        equipGrid.RefiningHeroId = nil
+    end
+    
+    EquipRefiningQuery(human, bagIndex, heroUuid, pos)
+end
+
+function EquipRefiningSave(human, bagIndex, heroUuid, pos)
+    local equipGrid, heroGrid, heroIndex = getEquipGrid(human, bagIndex, heroUuid, pos)
+    if not equipGrid then
+        return Broadcast.sendErr(human, Lang.EQUIP_GRID_ERR)
+    end
+
+    if false == EquipRefining_CheckCanDo(equipGrid.id) then
+        return
+    end
+
+    if equipGrid.RefiningEffectList then
+        equipGrid.effectList = equipGrid.RefiningEffectList
+    end
+
+    if equipGrid.RefiningHeroId then
+        equipGrid.exclusiveHeroId = equipGrid.RefiningHeroId
+    end
+
+    equipGrid.RefiningEffectList = nil
+    equipGrid.RefiningHeroId = nil
+
+    EquipLogic.checkAttr(equipGrid)
+    if not heroGrid then   
+       EquipLogic.sendEquipChange(human, bagIndex, equipGrid, EquipLogic.EQUIP_BAG_OP_CHANGE)
+    end
+
+     --刷新属性
+    if heroGrid and heroIndex and heroGrid.id then
+        ObjHuman.doCalcHero(human, heroIndex)
+        HeroLogic.sendHeroBagDynamic(human, heroGrid.id, heroIndex)
+        HeroEquip.query(human, heroGrid.id, heroIndex)
+    end
+
+    EquipRefiningQuery(human, bagIndex, heroUuid, pos)
 end

+ 21 - 0
script/module/equip/Handler.lua

@@ -49,4 +49,25 @@ end
 -- 取消装备未选择的洗练属性
 function CG_EQUIP_RETUN_RANDOM_ATTR(human, msg)
    EquipWash.CancelEquipRandomAttr(human, msg.bagIndex, msg.heroUuid, msg.pos)
+end
+
+
+-- 装备精炼查询
+function CG_EQUIP_REFINING_QUERY(human, msg)
+   EquipWash.EquipRefiningQuery(human, msg.bagIndex, msg.heroUuid, msg.pos)
+end
+
+-- 开始装备精炼
+function CG_EQUIP_REFINING_DO(human, msg)
+   EquipWash.EquipRefiningDo(human, msg.bagIndex, msg.heroUuid, msg.pos, msg.nOperate)
+end
+
+-- 放弃精炼
+function CG_EQUIP_REFINING_ABANDON(human, msg)
+   EquipWash.EquipRefiningAbandon(human, msg.bagIndex, msg.heroUuid, msg.pos)
+end
+
+-- 确认装备精炼
+function CG_EQUIP_REFINING_SAVE(human, msg)
+   EquipWash.EquipRefiningSave(human, msg.bagIndex, msg.heroUuid, msg.pos)
 end

+ 49 - 1
script/module/equip/Proto.lua

@@ -1,5 +1,6 @@
 local ItemData = require("bag.Proto").ItemData
 local Attr = require("role.Proto").Attr
+local EquipEffcect = require("bag.Proto").EQUIP_EFFCECT_DATA
 
 PutEquip = {
    {"equip",  1,   ItemData},  -- 装备属性
@@ -103,4 +104,51 @@ CG_EQUIP_RETUN_RANDOM_ATTR = {
     {"bagIndex",    1,  "int"},
     {"heroUuid",    1,  "string"},
     {"pos",         1,  "byte"},
-}
+}
+
+-- 装备精炼查询
+CG_EQUIP_REFINING_QUERY = {
+    {"bagIndex", 1, "int"},
+    {"heroUuid", 1, "string"},
+    {"pos",      1, "byte"},
+}
+
+-- 装备精炼查询回复
+GC_EQUIP_REFINING_QUERY = {
+    {"tEffectItem",         1,      ItemData},          -- 重置特效消耗物品
+    {"tHeroItem",           1,      ItemData},          -- 重置英雄消耗物品
+    {"tLefteffects",        3,      EquipEffcect},    -- 当前左边特性
+    {"tLeftHero",           1,      "string"},              -- 当前左边英雄名
+    {"tRighteffects",       3,      EquipEffcect},    -- 右边特性
+    {"tRightHero",          1,      "string"},              -- 右边英雄名
+}
+
+-- 开始装备精炼
+CG_EQUIP_REFINING_DO = {
+    {"bagIndex", 1, "int"},
+    {"heroUuid", 1, "string"},
+    {"pos",      1, "byte"},
+    {"nOperate", 1, "byte"},        -- 1 重置特效 2 重置专属,3-2个都选择
+}
+
+-- 开始装备精炼回包
+GC_EQUIP_REFINING_DO = {
+    {"tLefteffects",        3,      EquipEffcect},    -- 当前左边特性
+    {"tLeftHero",           1,      "string"},              -- 当前左边英雄名
+    {"tRighteffects",       3,      EquipEffcect},    -- 右边特性
+    {"tRightHero",          1,      "string"},              -- 右边英雄名
+}
+
+-- 放弃精炼
+CG_EQUIP_REFINING_ABANDON = {
+    {"bagIndex", 1, "int"},
+    {"heroUuid", 1, "string"},
+    {"pos",      1, "byte"},
+}
+
+-- 确认装备精炼
+CG_EQUIP_REFINING_SAVE = {
+    {"bagIndex", 1, "int"},
+    {"heroUuid", 1, "string"},
+    {"pos",      1, "byte"},
+}

+ 6 - 2
script/module/guide/GuideLogic.lua

@@ -924,8 +924,12 @@ function stepwenjuanchose(human, szChoseID)
         end
     end
 
-    local tPrize = GuideJumpExcel.Prize[1].tPrize
-    BagLogic.addItemList(human, tPrize, "guide")
+    if not human.db.bGetJumpPrize then
+        local tPrize = GuideJumpExcel.Prize[1].tPrize
+        BagLogic.addItemList(human, tPrize, "guide")
+        
+        human.db.bGetJumpPrize = true
+    end
 
     if true == bJump then
         local nMaxID = 0

+ 19 - 1
script/module/hero/Handler.lua

@@ -7,6 +7,7 @@ local HeroStrategyLogic = require("hero.HeroStrategyLogic")
 local HeroGem = require("hero.HeroGem")
 local HeroExclusiveWeapon = require("hero.HeroExclusiveWeapon")
 local HeroPubLogic = require("hero.HeroPubLogic")
+local HeroSeed = require("hero.HeroSeed")
 
 -- 请求英雄详细信息:静态
 function CG_HERO_BAG_STATIC(human,msg)
@@ -266,4 +267,21 @@ end
 
 function CG_HEROPUB_REWARD_GET(human,msg)
     HeroPubLogic.RewardGet(human)
-end
+end
+
+
+
+---------------------------------------英雄种子-----------------------------------------------
+function CG_HEROSEED_QUERY_ALL(human, msg)
+    HeroSeed.HeroSeed_Query_All(human, msg.heroID, msg.heroIndex)
+end
+
+function CG_HEROSEED_QUERY_SINGLE(human, msg)
+    HeroSeed.HeroSeed_Query_Single(human, msg.heroID, msg.heroIndex, msg.seedIdx)
+end
+
+function CG_HEROSEED_UPGRADE(human, msg)
+    HeroSeed.HeroSeed_UpGrade(human, msg.heroID, msg.heroIndex, msg.seedIdx, msg.opType)
+end
+
+---------------------------------------------------------------------------------------------

+ 167 - 4
script/module/hero/HeroLogic.lua

@@ -74,6 +74,9 @@ local HeroPubLogic = require("hero.HeroPubLogic")
 local WinnerRelicLogic = require("winnerRelic.WinnerRelicLogic")
 local GodsAreaNS = require("godsArea.GodsAreaNS")
 local Abs365CardLogic = require("absAct.Abs365CardLogic")
+local HeroSeed = require("hero.HeroSeed")
+local DeleteHeroConfig = require("excel.delteHero")
+
 
 HERO_MAX_STAR    =        15    -- 目前英雄最大星级
 
@@ -238,6 +241,72 @@ function TransformHeroEquipAttr(human)
 end
 
 
+local function playerNewUniqueTagCheck(human)
+	local playerNewUniqueTag= human.db.newUniqueTag
+	for _, v in pairs(DeleteHeroConfig.Sheet1) do
+		if v.newUniqueTag == playerNewUniqueTag then
+			return true
+		end
+	end
+
+	return false
+end
+
+local function isDelHero(human, heroUuid)
+	local playerNewUniqueTag= human.db.newUniqueTag
+	for _, v in pairs(DeleteHeroConfig.Sheet1) do
+		if v.newUniqueTag == playerNewUniqueTag and heroUuid == v.deleteHeros then
+			return true
+		end
+	end
+end
+
+
+local function getDelHeroIdxArr(human)
+	local delHeroIdxArr = {}
+
+	for i=1,human.db.heroBag[0] do
+		local heroGrid = human.db.heroBag[i]
+		if heroGrid and isDelHero(human, heroGrid.uuid) then
+			delHeroIdxArr[#delHeroIdxArr+1] = i
+		end
+	end
+
+	if #delHeroIdxArr == 0 then
+		return
+	end
+
+	return delHeroIdxArr
+end
+
+
+
+-- 临时处理异常获得的英雄
+local function deleteErrHero(human)
+	if human.db.delErrHeroTag then
+		return
+	end
+
+	if not playerNewUniqueTagCheck(human) then
+		human.db.delErrHeroTag = true
+		return
+	end
+
+	local delHeroIdxArr = getDelHeroIdxArr(human)
+	if delHeroIdxArr then
+		local logType =  "errHandle"
+		for _,heroIdx in ipairs(delHeroIdxArr) do
+			delHeroByIndex(human, heroIdx, logType)
+		end
+	end
+
+	human.db.delErrHeroTag = true
+end
+
+
+
+
+
 
 
 
@@ -250,6 +319,8 @@ function sendHeroBagList(human)
 	human.maxZDL.heroCnt = 0
 	human.maxZDL.zhandouli = 0
 
+	-- deleteErrHero(human)
+
 	local list = {}
 	for index = 1, human.db.heroBag[0] do
         local heroGrid = human.db.heroBag[index]
@@ -367,6 +438,7 @@ function sendHeroGridDynamic(human, heroGrid, index, isQuery)
     msgRet.canFuwen = FuwenLogic.isFuwenDot(human, heroGrid) == true and 1 or 0
     msgRet.canJueXing = isHeroJuexingDot(human, index, heroGrid) == true and 1 or 0
 	msgRet.canWeapon = HeroExclusiveWeapon.isWeaponDot(human, heroGrid) == true and 1 or 0
+	msgRet.canSeed = HeroSeed.isSeedDot(human, heroGrid) == true and 1 or 0
 	local bingShuState = BingshuLogic.isBingShuDot(human, heroGrid)
 	if bingShuState == -1 then
 		msgRet.canBingShu = -1 
@@ -593,6 +665,9 @@ function onGetNewHero(human, heroGrid, logType, heroIndex)
     yunYingActParam[2] = heroGrid.star
     yunYingActParam[3] = 1
     YunYingLogic.onCallBack(human, "onHeroStarChange", yunYingActParam)   
+
+	-- 获取新英雄
+	TriggerLogic.PublishEvent(TriggerDefine.EVENT_TYPE_GETPOINTHERO, human.db._id, 1, heroGrid.star, heroGrid.id)
 end
 
 -- 根据下标删除英雄
@@ -920,6 +995,35 @@ function getSkillDiffList(cf1, cf2)
 	return diffCnt, JUEXING_SKILL_DIFF_LIST
 end
 
+-- 英雄升星 16~20的额外条件表, 升到 key 星, 背包中还额外需要有 value[2] 个星级为 value[1] 的英雄
+local upStarExtraCond = {
+	[16] = {11, 10},
+	[17] = {11, 15},
+	[18] = {12, 10},
+	[19] = {12, 15},
+	[20] = {13, 10},
+}
+
+-- 升级额外条件检测
+local function upStarExtraCondCheck(human, nextStar)
+	local extraCond = upStarExtraCond[nextStar]
+	if not extraCond then
+		return true
+	end
+
+	local starCond = extraCond[1]
+	local numCond = extraCond[2]
+	local numCorrect = CalcStarHeroCnt(human, starCond)
+
+	if numCorrect < numCond then
+		return Broadcast.sendErr(human, Util.format(Lang.HERO_UPSTAR_EXTRA_COND, starCond, numCond))
+	end
+
+	return true
+end
+
+
+
 -- 英雄觉醒(升星)预览
 local JUEXING_SPEED_UP = {[4]=10}
 local JUEXING_ATK_UP = {[5]=40,[6]=40,[7]=40,[8]=40,[9]=40,[10]=20,[11]=20,[12]=20}
@@ -948,7 +1052,12 @@ function heroJueXingQuery(human, heroID, heroIndex)
 	if not nextAttrConfig then 
        return sendHeroJueXingMax(human, heroID, heroIndex)
     end
-	
+
+	-- 额外条件判断
+	-- if not upStarExtraCondCheck(human, nextAttrConfig.star) then
+	-- 	return
+	-- end
+
 
 	local msgRet = Msg.gc.GC_HERO_JUEXING_QUERY
 	local dataNet = msgRet.data
@@ -1052,6 +1161,11 @@ function heroJueXingDo(human, heroID, heroIndex, inputIDList, inputIndexList)
 		return
 	end
 
+	-- 额外条件判断
+	if not upStarExtraCondCheck(human, nextAttrConfig.star) then
+		return
+	end
+
 	-- 判断消耗材料
 	local needItemCnt = attrConfig.jinjieshi
 	if not BagLogic.checkItemCnt(human, ItemDefine.ITEM_HERO_UPGRADE_ID, needItemCnt) then
@@ -1168,6 +1282,7 @@ function heroJueXingDo(human, heroID, heroIndex, inputIDList, inputIndexList)
 
 	TriggerLogic.PublishEvent(TriggerDefine.HERO_YINGHUN_JINHUA, human.db._id, 1)
 
+	TriggerLogic.PublishEvent(TriggerDefine.EVENT_TYPE_GETPOINTHERO, human.db._id, 1, newstar, heroID)
 
 	if heroConfig.grade >= HeroDefine.HERO_SSR_GRADE then
 		HeroPubLogic.UpdateHero(human, HeroPubLogic.HERO_OP_UPSTAR, heroID, heroGrid.uuid)
@@ -1482,6 +1597,18 @@ function sendHuituiQuery(human, heroID, heroIndex)
 		end
 	end
 
+	-- 英雄种子返还材料
+	local seedReturnItem = HeroSeed.CalcReturnItem(human, heroGrid)
+	if seedReturnItem then
+		for _, itemInfo in ipairs(seedReturnItem) do
+			if msgRet.returnItems[0] >= #msgRet.returnItems then
+				break
+			end
+			
+			msgRet.returnItems[0] = msgRet.returnItems[0] + 1
+			Grid.makeItem(msgRet.returnItems[msgRet.returnItems[0]], itemInfo[1], itemInfo[2])
+		end
+	end
 
 	msgRet.returnHeros[0] = 0
 	for star, v in pairs(heros) do
@@ -1548,6 +1675,20 @@ function huituiHero(human, heroID, heroIndex)
 		HeroExclusiveWeapon.SetHeroWeaponLv(human, heroID, heroIndex, 0)
 	end
 
+	-- 英雄种子返还材料
+	local seedReturnItem = HeroSeed.CalcReturnItem(human, heroGrid)
+	if seedReturnItem then
+		for _, itemInfo in ipairs(seedReturnItem) do
+			local itemId = itemInfo[1]
+			local itemCnt = itemInfo[2]
+			items[itemId] = (items[itemId] or 0) + itemCnt
+		end
+
+		-- 重置英雄所有种子等级
+		HeroSeed.ResetSeedLv(human, heroGrid)
+	end
+
+
 	heroGrid.star = star
 	heroGrid.lv = targetLv
 	XingYaoGongMing.onDelHero(human,heroGrid,heroIndex)
@@ -1880,6 +2021,11 @@ function isHeroDot(human, heroGrid)
 		return true
 	end
 
+	-- 英雄种子
+	if HeroSeed.isSeedDot(human, heroGrid) then
+		return true
+	end
+
 end
 
 -- 升级判定
@@ -2143,10 +2289,13 @@ function getResetReturnItems(heroGrid)
 	end
 
     -- 升星材料
-    for i = 1,heroGrid.star do
+    for i = 1,heroGrid.star-1 do
         local attrConfig = HeroDefine.getAttrConfig(heroGrid.id, i)
         if attrConfig then
-			if  attrConfig.jinjieshi > 0 then RESET_RETURN_ITEMS[ItemDefine.ITEM_HERO_UPGRADE_ID] = (RESET_RETURN_ITEMS[ItemDefine.ITEM_HERO_UPGRADE_ID] or 0) + attrConfig.jinjieshi end
+			if  attrConfig.jinjieshi > 0 then 
+				RESET_RETURN_ITEMS[ItemDefine.ITEM_HERO_UPGRADE_ID] = (RESET_RETURN_ITEMS[ItemDefine.ITEM_HERO_UPGRADE_ID] or 0) + attrConfig.jinjieshi 
+
+			end
             for j = 1,#attrConfig.needItems do
                 RESET_RETURN_ITEMS[attrConfig.needItems[j][1]] = (RESET_RETURN_ITEMS[attrConfig.needItems[j][1]] or 0) + attrConfig.needItems[j][2]
             end
@@ -2371,7 +2520,6 @@ function AllHeroEquipSkin(human)
 	end
 end
 
-
 -- 统计英雄背包中, 每类SSR, UR英雄的最高星级
 function GetHeroMaxStarList(human)
 	local noCalcHeroList = {}
@@ -2404,6 +2552,20 @@ function GetHeroMaxStarList(human)
 	return maxStarList
 end
 
+-- 统计背包中符合星级条件的英雄数量
+function CalcStarHeroCnt(human, starCond, excludeList)
+	local correctNum = 0
+	for index = 1, human.db.heroBag[0] do
+        local heroGrid = human.db.heroBag[index]
+        if heroGrid and heroGrid.star >= starCond and (not excludeList or not excludeList[heroGrid.uuid]) then
+			correctNum = correctNum + 1
+		end
+	end
+
+	return correctNum
+end
+
+
 
 -- 获取背包中同Id最高星级的英雄
 function GetMaxStarHero(human, heroId)
@@ -2813,6 +2975,7 @@ function heroJueXingOneClickDo(human, tHeroData)
 
 		TriggerLogic.PublishEvent(TriggerDefine.HERO_YINGHUN_JINHUA, human.db._id, 1)
 
+		TriggerLogic.PublishEvent(TriggerDefine.EVENT_TYPE_GETPOINTHERO, human.db._id, 1, newstar,  v.nHeroID)
 
 		if heroConfig.grade >= HeroDefine.HERO_SSR_GRADE then
 			HeroPubLogic.UpdateHero(human, HeroPubLogic.HERO_OP_UPSTAR, v.nHeroID, heroGrid.uuid)

Некоторые файлы не были показаны из-за большого количества измененных файлов