From 732aca3b8264a1cfc49975de2a92a6d6030befe7 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 13 十月 2025 14:12:17 +0800
Subject: [PATCH] 129 【战斗】战斗系统-服务端(主线支持定制掉落装备;)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py | 326 +++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 246 insertions(+), 80 deletions(-)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py
index fba8115..15c11a5 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py
@@ -17,6 +17,7 @@
import ChConfig
import GameWorld
+import TurnAttack
import ShareDefine
import IpyGameDataPY
import PlayerControl
@@ -24,9 +25,11 @@
import ItemControler
import IPY_GameWorld
import NetPackCommon
+import PlayerArena
import ItemCommon
import PlayerTask
import NPCCommon
+import BattleObj
import ChEquip
import ObjPool
@@ -65,17 +68,17 @@
ipyData = ipyDataMgr.GetMainChapterByIndex(chapterCount - 1)
return [booty[0] for booty in ipyData.GetDailyBootyUpperList()]
-def OnPlayerLineupAttackResult(curPlayer, atkObj, killObjIDList, useSkill, mapID, funcLineID):
+def OnPlayerLineupAttackResult(curPlayer, atkObj, killObjList, useSkill, mapID, funcLineID):
## 回合战斗主动发起的玩家阵容攻击结果额外处理 ,一般处理副本相关的掉落、奖励等
if mapID == ChConfig.Def_FBMapID_Main:
- __doKillAward(curPlayer, atkObj, killObjIDList)
+ __doKillAward(curPlayer, atkObj, killObjList)
return
-def __doKillAward(curPlayer, atkObj, killObjIDList):
+def __doKillAward(curPlayer, atkObj, killObjList):
## 计算击杀奖励
- if not killObjIDList:
+ if not killObjList:
GameWorld.DebugLog("没有击杀不需要处理!")
return
# 结算经验
@@ -87,12 +90,12 @@
GameWorld.DebugLog("增加经验: totalExp=%s,unXiantaoCntExp=%s" % (totalExp, unXiantaoCntExp))
PlayerControl.PlayerControl(curPlayer).AddExp(totalExp, ShareDefine.Def_ViewExpType_KillNPC)
- __doMainDrop(curPlayer)
+ __doMainDrop(curPlayer, killObjList)
return
-def __doMainDrop(curPlayer):
+def __doMainDrop(curPlayer, killObjList):
# 装备掉落
- if __doDropEquip(curPlayer) == -1:
+ if __doDropEquip(curPlayer, killObjList) == -1:
return
playerID = curPlayer.GetPlayerID()
@@ -128,6 +131,22 @@
if dropBootyCnt <= 0:
continue
+ itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)
+ if not itemData:
+ continue
+
+ # 判断挑战券
+ if itemData.GetType() == ChConfig.Def_ItemType_AutoUseMoney:
+ curEff = itemData.GetEffectByIndex(0)
+ effID = curEff.GetEffectID()
+ moneyType = curEff.GetEffectValue(1)
+ if effID == ChConfig.Def_Effect_ItemGiveMoney and moneyType == ShareDefine.TYPE_Price_ArenaTicket:
+ curMoney = PlayerControl.GetMoney(curPlayer, ShareDefine.TYPE_Price_ArenaTicket)
+ storeMax = PlayerArena.GetArenaTicketStoreMax(curPlayer)
+ if curMoney >= storeMax:
+ GameWorld.DebugLog("挑战券已达存储上限! itemID=%s,curMoney=%s >= %s" % (itemID, curMoney, storeMax), playerID)
+ continue
+
dropCntRange = bootyDropCntDict[itemID]
if not isinstance(dropCntRange, (list, tuple)) or len(dropCntRange) != 2:
continue
@@ -160,15 +179,36 @@
return
-def __doDropEquip(curPlayer):
+def __doDropEquip(curPlayer, killObjList):
## 主线掉落装备
playerID = curPlayer.GetPlayerID()
- unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip)
- dropOneNeed = IpyGameDataPY.GetFuncCfg("MainEquipDrop", 1) # 每消耗X个战锤掉落一件装备
- dropEquipCnt = unXiantaoCntEquip / dropOneNeed
+ unXiantaoCntEquip = PlayerControl.GetUnXiantaoCntEquip(curPlayer)
+ bossTypeDropInfo = IpyGameDataPY.GetFuncCfg("MainEquipDrop", 1) # 每消耗X个战锤掉落一件装备
+ fightPoint = max(curPlayer.GetFightPoint(), 1) # 消耗倍率也是掉落倍率
+ dropEquipCnt = 0
+ objDropCntDict = {}
+ for tagObj in killObjList:
+ tagID = tagObj.GetID()
+ npcID = tagObj.GetNPCID()
+ if not npcID:
+ continue
+ npcData = NPCCommon.GetNPCDataPy(npcID)
+ if not npcData:
+ continue
+ bossType = npcData.GetBossType()
+ if bossType not in bossTypeDropInfo:
+ continue
+ dropCnt = GameWorld.GetResultByRandomList(bossTypeDropInfo[bossType])
+ if not dropCnt:
+ continue
+ dropCnt *= fightPoint # 多倍掉落
+ objDropCntDict[tagID] = [tagObj, dropCnt, bossType]
+ dropEquipCnt += dropCnt
+
if dropEquipCnt <= 0:
- GameWorld.DebugLog("主线暂不能掉落! unXiantaoCntEquip=%s,dropOneNeed=%s,dropEquipCnt=%s" % (unXiantaoCntEquip, dropOneNeed, dropEquipCnt), playerID)
+ GameWorld.DebugLog("主线暂不能掉落! unXiantaoCntEquip=%s,dropEquipCnt=%s" % (unXiantaoCntEquip, dropEquipCnt), playerID)
return
+ # 根据掉落背包空间修正最终可掉落装备数
dropEquipCnt = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptIdentify, dropEquipCnt)
if not dropEquipCnt:
GameWorld.DebugLog("掉落背包已满!", playerID)
@@ -178,52 +218,120 @@
ipyData = IpyGameDataPY.GetIpyGameData("TreeLV", treeLV)
if not ipyData:
return
- equipColorRateList = ipyData.GetEquipColorRateList()
- GameWorld.DebugLog("主线掉落装备: unXiantaoCntEquip=%s,dropEquipCnt=%s,treeLV=%s,equipColorRateList=%s" % (unXiantaoCntEquip, dropEquipCnt, treeLV, equipColorRateList), playerID)
+ GameWorld.DebugLog("主线掉落装备: unXiantaoCntEquip=%s,dropEquipCnt=%s,treeLV=%s,objDropCntDict=%s"
+ % (unXiantaoCntEquip, dropEquipCnt, treeLV, objDropCntDict), playerID)
+ dropAppointEquipDict = IpyGameDataPY.GetFuncEvalCfg("MainDropAppoint", 1, {})
+ appointDropCntMax = max(dropAppointEquipDict) if dropAppointEquipDict else 0
- maxRate = 10000
- totalRate = 0
- colorRateList = []
- for equipColor, colorRate in enumerate(equipColorRateList, 1):
- if not colorRate:
- continue
- totalRate += colorRate
- colorRateList.append([totalRate, equipColor])
-
- if totalRate != maxRate:
- GameWorld.SendGameError("GameWarning", "CutTreeTotalRateError:%s!=%s,treeLV=%s" % (totalRate, maxRate, treeLV))
- if not colorRateList:
- return
- GameWorld.DebugLog(" colorRateList=%s,totalRate=%s" % (colorRateList, totalRate), playerID)
-
- for _ in range(dropEquipCnt):
- itemColor = GameWorld.GetResultByRandomList(colorRateList)
- if not itemColor:
- continue
- equipIDList = NPCCommon.__GetEquipIDList(0, color=itemColor, placeList=ChConfig.Def_MainEquipPlaces, findType="MainEquipDrop")
- if not equipIDList:
- continue
- randEquipID = random.choice(equipIDList)
-
- curItem = ItemControler.GetOutPutItemObj(randEquipID, 1, False, curPlayer=curPlayer)
- if curItem == None:
- continue
- curItem.SetIsBind(1) # 为1时代表是掉落
-
- #GameWorld.DebugLog("掉落装备: randEquipID=%s,%s" % (randEquipID, curItem.GetGUID()), playerID)
- if not ItemControler.DoLogic_PutItemInPack(curPlayer, curItem, packIndexList=[IPY_GameWorld.rptIdentify]):
+ for tagID, dropInfo in objDropCntDict.items():
+ tagObj, dropCnt, bossType = dropInfo
+ if hasattr(ipyData, "GetEquipColorRateList%s" % bossType):
+ equipColorRateList = getattr(ipyData, "GetEquipColorRateList%s" % bossType)()
+ else:
+ equipColorRateList = ipyData.GetEquipColorRateList()
+
+ GameWorld.DebugLog("tagID=%s,bossType=%s,dropCnt=%s,treeLV=%s,equipColorRateList=%s"
+ % (tagID, bossType, dropCnt, treeLV, equipColorRateList), playerID)
+ if not equipColorRateList:
continue
- unXiantaoCntEquip -= dropOneNeed
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntEquip, unXiantaoCntEquip)
+ totalRate = 0
+ colorRateList = []
+ for equipColor, colorRate in enumerate(equipColorRateList, 1):
+ if not colorRate:
+ continue
+ totalRate += colorRate
+ colorRateList.append([totalRate, equipColor])
+
+ #maxRate = 10000
+ #if totalRate != maxRate:
+ # GameWorld.SendGameError("GameWarning", "CutTreeTotalRateError:%s!=%s,treeLV=%s" % (totalRate, maxRate, treeLV))
+ if not colorRateList:
+ return
+ GameWorld.DebugLog(" colorRateList=%s,totalRate=%s" % (colorRateList, totalRate), playerID)
+ for _ in range(dropCnt):
+ if dropEquipCnt <= 0:
+ break
+
+ setAttrDict = None
+ appointDropEquipCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AppointDropEquipCnt) + 1
+ if appointDropEquipCnt in dropAppointEquipDict:
+ appointInfo = dropAppointEquipDict[appointDropEquipCnt]
+ randEquipID = appointInfo[0]
+ equipLV = appointInfo[1] if len(appointInfo) > 1 else 0
+ appointID = appointInfo[2] if len(appointInfo) > 2 else 0
+ setAttrDict = {}
+ if equipLV > 0:
+ setAttrDict["%s" % ShareDefine.Def_IudetItemLV] = equipLV
+ if appointID:
+ setAttrDict[ShareDefine.Def_CItemKey_AppointID] = appointID
+ GameWorld.DebugLog("定制掉落第%s次: equipID=%s,setAttrDict=%s" % (appointDropEquipCnt, randEquipID, setAttrDict))
+ else:
+ itemColor = GameWorld.GetResultByRandomList(colorRateList)
+ if not itemColor:
+ continue
+ equipIDList = NPCCommon.__GetEquipIDList(0, color=itemColor, placeList=ChConfig.Def_MainEquipPlaces, findType="MainEquipDrop")
+ if not equipIDList:
+ continue
+ randEquipID = random.choice(equipIDList)
+
+ curItem = ItemControler.GetOutPutItemObj(randEquipID, 1, False, curPlayer=curPlayer, setAttrDict=setAttrDict)
+ if curItem == None:
+ continue
+ curItem.SetIsBind(1) # 为1时代表是掉落
+ #GameWorld.DebugLog("掉落装备: randEquipID=%s,%s" % (randEquipID, curItem.GetGUID()), playerID)
+ if not ItemControler.DoLogic_PutItemInPack(curPlayer, curItem, packIndexList=[IPY_GameWorld.rptIdentify]):
+ continue
+
+ dropEquipCnt -= 1
+
+ if appointDropEquipCnt <= appointDropCntMax:
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_AppointDropEquipCnt, appointDropEquipCnt)
return
-def GMTestKillDrop(curPlayer, unXiantao):
- ## GM测试掉落
- unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip) + unXiantao
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntEquip, unXiantaoCntEquip)
- GameWorld.DebugAnswer(curPlayer, "未结算装备战锤数: %s" % unXiantaoCntEquip)
+def GMTestKill(curPlayer, useXiantao):
+ ## GM测试击杀
+
+ mainFightMgr = TurnAttack.GetMainFightMgr(curPlayer)
+ turnFight = mainFightMgr.turnFight
+ if not turnFight.isInFight():
+ GameWorld.DebugAnswer(curPlayer, "非主线战斗中!")
+ return
+
+ useSkill = None
+ batObjMgr = BattleObj.GetBatObjMgr()
+
+ # 随便取一个武将击杀对方所有怪物即可
+ atkObj = None
+ batFactionA = turnFight.getBatFaction(ChConfig.Def_FactionA)
+ batLineup = batFactionA.getBatlineup(1)
+ for objID in batLineup.posObjIDDict.values():
+ atkObj = batObjMgr.getBatObj(objID)
+ if atkObj.IsAlive():
+ break
+
+ if not atkObj:
+ GameWorld.DebugAnswer(curPlayer, "主阵容没有存活武将!")
+ return
+
+ clientPack = ChPyNetSendPack.tagSCTurnFightReportSign()
+ clientPack.Sign = 0
+ NetPackCommon.SendFakePack(curPlayer, clientPack) # 标记开始
+
+ killObjList = []
+ batFactionB = turnFight.getBatFaction(ChConfig.Def_FactionB)
+ batLineup = batFactionB.getBatlineup(1)
+ for objID in batLineup.posObjIDDict.values():
+ tagObj = batObjMgr.getBatObj(objID)
+ if tagObj.IsAlive():
+ killObjList.append(tagObj)
+ TurnAttack.SetObjKilled(turnFight, tagObj, atkObj, useSkill)
+
+ unXiantaoCntExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntExp) + useXiantao
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntExp, unXiantaoCntExp)
+ GameWorld.DebugAnswer(curPlayer, "未结算经验战锤数: %s" % unXiantaoCntExp)
+ GameWorld.DebugAnswer(curPlayer, "未结算装备战锤数: %s" % PlayerControl.AddUnXiantaoCntEquip(curPlayer, useXiantao))
chapterID = PlayerControl.GetMainLevelNowInfo(curPlayer)[0]
chapterIpyData = IpyGameDataPY.GetIpyGameData("MainChapter", chapterID)
if chapterIpyData:
@@ -231,11 +339,16 @@
for itemID, upperCnt in DailyBootyUpperList:
if upperCnt <= 0:
continue
- unXiantaoCntBooty = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntBooty % itemID) + unXiantao
+ unXiantaoCntBooty = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntBooty % itemID) + useXiantao
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntBooty % itemID, unXiantaoCntBooty)
GameWorld.DebugAnswer(curPlayer, "未结算战利品(%s)战锤数: %s" % (itemID, unXiantaoCntBooty))
- __doMainDrop(curPlayer)
+ OnPlayerLineupAttackResult(curPlayer, atkObj, killObjList, useSkill, turnFight.mapID, turnFight.funcLineID)
+ turnFight.checkOverByKilled()
+
+ # 标记结束
+ clientPack.Sign = 1
+ NetPackCommon.SendFakePack(curPlayer, clientPack)
return
#// B4 15 主线掉落物品操作 #tagCSMainDropItemOP
@@ -315,50 +428,58 @@
def __doDecomposeMainEquip(curPlayer, itemIndexList):
playerID = curPlayer.GetPlayerID()
GameWorld.DebugLog("分解主线装备: itemIndexList=%s" % (itemIndexList), playerID)
- IdentifyPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptIdentify)
-
- moneyType = IpyGameDataPY.GetFuncCfg("MainEquipDrop", 2)
- if not moneyType:
+ moneyType, moneyBase = IpyGameDataPY.GetFuncEvalCfg("MainEquipDrop", 2)
+ if not moneyType or not moneyBase:
return
+
+ equipDict = {}
+ IdentifyPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptIdentify)
+ for index in range(IdentifyPack.GetCount()):
+ curEquip = IdentifyPack.GetAt(index)
+ if not ItemCommon.CheckItemCanUse(curEquip):
+ #GameWorld.DebugLog("物品为空或不可用: index=%s" % index, playerID)
+ continue
+ if not ItemCommon.GetIsMainEquip(curEquip):
+ #GameWorld.DebugLog("非主线装备: index=%s" % index, playerID)
+ continue
+ equipDict[index] = curEquip
+
+ if not equipDict:
+ return
+
+ equipCnt = len(equipDict)
+ unXiantaoCntEquip = PlayerControl.GetUnXiantaoCntEquip(curPlayer)
+ perEquipXiantao = unXiantaoCntEquip / float(equipCnt) if equipCnt > 1 else unXiantaoCntEquip
+ decomposeMoney = max(1, moneyBase * perEquipXiantao) # 至少1个
+ GameWorld.DebugLog("unXiantaoCntEquip=%s,equipCnt=%s,perEquipXiantao=%s,equipIndexList=%s"
+ % (unXiantaoCntEquip, equipCnt, perEquipXiantao, equipDict.keys()), playerID)
+ GameWorld.DebugLog("moneyBase=%s,decomposeMoney=%s" % (moneyBase, decomposeMoney), playerID)
moneyTotal = 0
decomposeCnt = 0
decomposeIndexList = []
for itemIndex in itemIndexList:
- if itemIndex < 0 or itemIndex >= IdentifyPack.GetCount():
+ if itemIndex not in equipDict:
continue
- curEquip = IdentifyPack.GetAt(itemIndex)
- if not ItemCommon.CheckItemCanUse(curEquip):
- GameWorld.DebugLog("物品为空或不可用: itemIndex=%s" % itemIndex, playerID)
- continue
-
- if not ItemCommon.GetIsMainEquip(curEquip):
- GameWorld.DebugLog("非主线装备: itemIndex=%s" % itemIndex, playerID)
- continue
- itemColor = curEquip.GetItemColor()
-
- colorIpyData = IpyGameDataPY.GetIpyGameData("EquipColor", itemColor)
- if not colorIpyData:
- return
- moneyBase = colorIpyData.GetMoneyBase() # 分解货币基础
- if not moneyBase:
- return
- # 可以处理一些加成
-
- decomposeMoney = moneyBase
+ curEquip = equipDict[itemIndex]
moneyTotal += decomposeMoney
- GameWorld.DebugLog(" itemIndex=%s,itemColor=%s,moneyBase=%s,decomposeMoney=%s,%s"
- % (itemIndex, itemColor, moneyBase, decomposeMoney, moneyTotal), playerID)
+ GameWorld.DebugLog(" itemIndex=%s,moneyBase=%s,perEquipXiantao=%s,decomposeMoney=%s,总:%s"
+ % (itemIndex, moneyBase, perEquipXiantao, decomposeMoney, moneyTotal), playerID)
ItemCommon.DelItem(curPlayer, curEquip, curEquip.GetCount(), True, ChConfig.ItemDel_EquipDecompose)
decomposeIndexList.append(itemIndex)
decomposeCnt += 1
+ unXiantaoCntEquip -= perEquipXiantao
if not moneyTotal:
return
+ moneyTotal = int(round(moneyTotal)) # 四舍五入取整
+ unXiantaoCntEquip = PlayerControl.SetUnXiantaoCntEquip(curPlayer, unXiantaoCntEquip)
+ GameWorld.DebugLog("moneyTotal=%s,unXiantaoCntEquip=%s" % (moneyTotal, unXiantaoCntEquip), playerID)
+
PlayerControl.GiveMoney(curPlayer, moneyType, moneyTotal, "DecomposeMainEquip", isSysHint=False)
PlayerTask.AddTaskValue(curPlayer, ChConfig.TaskType_EquipDecompose, decomposeCnt)
return
@@ -408,3 +529,48 @@
clientPack.Count = len(clientPack.DropBootyList)
NetPackCommon.SendFakePack(curPlayer, clientPack)
return
+
+def OnTurnFightOver(curPlayer, turnFight, mapID, funcLineID, overMsg):
+ ## 回合战斗结束
+
+ if not curPlayer:
+ return
+
+ #winFaction = turnFight.winFaction
+ isWin = turnFight.isWin
+
+ playerID = curPlayer.GetPlayerID()
+ mainFightMgr = TurnAttack.GetMainFightMgr(curPlayer)
+ chapterID, levelNum, wave = PlayerControl.GetMainLevelNowInfo(curPlayer)
+
+ if not isWin:
+ nextWave = max(1, wave - 1)
+ nowValue = PlayerControl.SetMainLevelNowInfo(curPlayer, chapterID, levelNum, nextWave)
+ GameWorld.DebugLog("主线小怪战斗失败,降一波! chapterID=%s,levelNum=%s,wave=%s,nextWave=%s,nowValue=%s"
+ % (chapterID, levelNum, wave, nextWave, nowValue), playerID)
+ return
+
+ if turnFight.haveNextLineup():
+ GameWorld.DebugLog("主线小怪战斗胜利,有下一小队! chapterID=%s,levelNum=%s,wave=%s" % (chapterID, levelNum, wave), playerID)
+ return
+
+ # 获胜过波
+ if wave < mainFightMgr.waveMax:
+ nextWave = min(mainFightMgr.waveMax, wave + 1)
+ nowValue = PlayerControl.SetMainLevelNowInfo(curPlayer, chapterID, levelNum, nextWave)
+ GameWorld.DebugLog("主线小怪波战斗胜利,下一波! chapterID=%s,levelNum=%s,wave=%s,nextWave=%s,nowValue=%s"
+ % (chapterID, levelNum, wave, nextWave, nowValue), playerID)
+ else:
+ GameWorld.DebugLog("主线小怪波战斗胜利,最后一波循环刷! chapterID=%s,levelNum=%s,wave=%s" % (chapterID, levelNum, wave), playerID)
+
+ # 小怪可能会退波,所以只在有超过已过关卡进度时才更新值
+ hisPassValue = PlayerControl.GetMainLevelPassValue(curPlayer)
+ curPassValue = PlayerControl.ComMainLevelValue(chapterID, levelNum, wave)
+ if curPassValue > hisPassValue:
+ GameWorld.DebugLog("更新当前过关进度! curPassValue=%s,hisPassValue=%s" % (curPassValue, hisPassValue), playerID)
+ PlayerControl.SetMainLevelPassValue(curPlayer, curPassValue)
+ else:
+ GameWorld.DebugLog("未超过当前过关进度,不更新! curPassValue=%s <= hisPassValue=%s" % (curPassValue, hisPassValue), playerID)
+
+ return
+
--
Gitblit v1.8.0