From 9ec66731c8a551035958aebe1fa974a140b99cf1 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期三, 02 七月 2025 17:34:10 +0800
Subject: [PATCH] 129 【战斗】战斗系统-服务端(初版战斗,支持基础的三维属性战斗,支持简单的普攻技能、怒气技能、回血技能;主线章节关卡过关支持;阵容保存支持多阵容;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py |  133 ++++++++++++++++++++++++++++++-------------
 1 files changed, 92 insertions(+), 41 deletions(-)

diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
index 806394e..e0edf24 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -71,6 +71,7 @@
 import IpyGameDataPY
 import PlayerGubao
 import PlayerState
+import TurnAttack
 import PyGameData
 import PlayerTeam
 import NPCHurtMgr
@@ -149,7 +150,7 @@
 def SetSuppressFightPower(curNPC, value): return curNPC.SetThunderDef(min(value, ShareDefine.Def_UpperLimit_DWord))
 def GetCommendFightPower(curNPC): return curNPC.GetFireDef() # 火防代表推荐战力
 def GetDropOwnerType(curNPC): return curNPC.GetThunderAtk() # 雷攻代表掉落归属类型
-def GetFaction(curNPC): return curNPC.GetCountry()
+def GetFaction(curNPC): return GameObj.GetFaction(curNPC)
 def GetSkillAtkRate(curNPC): return curNPC.GetPoisionAtk() # 毒攻代表NPC技能伤害加成万分率
 def GetFinalHurt(curNPC): return curNPC.GetFireAtk() # 火攻代表NPC最终固定伤害加成, 普攻也有效果
 def SetFinalHurt(curNPC, hurt): return curNPC.SetFireAtk(hurt) # 火攻代表NPC最终固定伤害加成, 普攻也有效果
@@ -2261,7 +2262,9 @@
 #  @return 
 def SetDeadEx(curNPC):
     summon_List = []
+    objID = curNPC.GetID()
     npcid = curNPC.GetNPCID()
+    GameWorld.DebugLog("SetDeadEx objID=%s,npcID=%s" % (objID, npcid))
     #将涉及到C++中列表删除的功能,统一改成 -> 复制Py列表后,然后进行删除逻辑 
     for index in range(curNPC.GetSummonCount()):
         curSummonNPC = curNPC.GetSummonNPCAt(index)
@@ -2322,9 +2325,20 @@
                 break
             
     # C++设置npc死亡
+    notifyClient = True
+    tfMgr = TurnAttack.GetTurnFightMgr()
+    turnFight = tfMgr.getNPCTurnFight(objID)
+    if turnFight:
+        notifyClient = False # 回合制战斗的由py自己通知
+        # //04 07 NPC消失#tagNPCDisappear 此处通知消失,与回合制死亡区分
+        clientPack = ChNetSendPack.tagNPCDisappear()
+        clientPack.NPCID = [objID]
+        clientPack.Count = len(clientPack.NPCID)
+        turnFight.addBatPack(clientPack)
     curNPC.SetDead(curNPC.GetDictByKey(ChConfig.Def_NPCDead_Reason),
                    curNPC.GetDictByKey(ChConfig.Def_NPCDead_KillerType),
-                   curNPC.GetDictByKey(ChConfig.Def_NPCDead_KillerID))
+                   curNPC.GetDictByKey(ChConfig.Def_NPCDead_KillerID), notifyClient)
+    tfMgr.delNPCGUID(objID)
     return
 
 def GameServer_KillGameWorldBoss(bossID, killPlayerName, hurtValue, isNotify=True, killerIDList=[]):
@@ -3627,41 +3641,35 @@
             GameWorld.DebugLog("NPC复活,套上光环: objID=%s,npcID=%s,skillID=%s" % (curNPC.GetID(), curNPC.GetNPCID(), useSkill.GetSkillID()))
             SkillShell.NPCUseSkill(curNPC, useSkill, tick)
             
-        curNPC.NotifyAppear() # 最终统一通知NPC出现
-        self.NotifyNPCShow(curNPCID, tick) # 广播NPC秀
+        self.__notifyAppear() # 最终统一通知NPC出现
         return
     
-    def NotifyNPCShow(self, npcID, tick):
-        ## 广播NPC秀
-        mapID = GameWorld.GetMap().GetMapID()
-        npcShowIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCShow", npcID, mapID)
-        if not npcShowIpyData:
-            #GameWorld.DebugLog("不需要NPC秀: npcID=%s" % npcID)
+    def __notifyAppear(self):
+        ## //04 06 NPC出现#tagNPCAppear,可能也有 04 08 玩家召唤NPC出现#tagPlayerSummonNPCAppear,卡牌先简化,只使用0406
+        curNPC = self.__Instance
+        objID = curNPC.GetID()
+        turnFight = TurnAttack.GetTurnFightMgr().getNPCTurnFight(objID)
+        if not turnFight:
+            # 非回合制怪保留原通知
+            curNPC.NotifyAppear()
             return
-        #if npcShowIpyData.GetBindMissionID():
-        #    #GameWorld.DebugLog("有绑定任务ID的,前端自己展示NPC秀!mapID=%s,npcID=%s" % (mapID, npcID))
-        #    return
-        if npcShowIpyData.GetShowType():
-            #GameWorld.DebugLog("前端自己展示的NPC秀!mapID=%s,npcID=%s" % (mapID, npcID))
-            return
-        endTick = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Def_FBDict_NPCShowEndTick % npcID)
-        if endTick:
-            #GameWorld.DebugLog("已经存在同个NPCID的NPC秀,不重复展示!npcID=%s" % (npcID))
-            return
-        endTick = tick + npcShowIpyData.GetProtectTime()
-        GameWorld.GetGameFB().SetGameFBDict(ChConfig.Def_FBDict_NPCShowEndTick % npcID, endTick)
         
-        # 广播地图内玩家展示NPC秀
-        npcShowPack = ChPyNetSendPack.tagMCNPCShow()
-        npcShowPack.NPCID = npcID
-        playerManager = GameWorld.GetMapCopyPlayerManager()
-        for index in xrange(playerManager.GetPlayerCount()):
-            player = playerManager.GetPlayerByIndex(index)
-            if not player.GetPlayerID():
-                continue
-            NetPackCommon.SendFakePack(player, npcShowPack)
-            
-        GameWorld.DebugLog("开始NPC秀: npcID=%s,tick=%s,endTick=%s" % (npcID, tick, endTick))
+        # 回合制怪不通知,统一由 // B4 24 回合战斗初始化 #tagSCTurnFightInit
+        
+        # 使用bt版本开发测试暂时留着,方便测试,正式需删除通知
+        if turnFight.curPlayer:
+            clientPack = ChNetSendPack.tagNPCAppear()
+            clientPack.ObjID = objID
+            clientPack.NPCID = curNPC.GetNPCID()
+            clientPack.NPCHP = curNPC.GetHP()
+            clientPack.NPCHPEx = curNPC.GetHPEx()
+            clientPack.MaxHP = curNPC.GetMaxHP()
+            clientPack.MaxHPEx = curNPC.GetMaxHPEx()
+            clientPack.CurLV = curNPC.GetCurLV()
+            clientPack.PosX = curNPC.GetPosX()
+            clientPack.PosY = curNPC.GetPosY()
+            clientPack.Speed = curNPC.GetSpeed()
+            NetPackCommon.SendFakePack(turnFight.curPlayer, clientPack)
         return
     
     #---------------------------------------------------------------------
@@ -3771,12 +3779,61 @@
     #  @return 返回值无意义
     #  @remarks 刷新NPC属性和行为状态
     def RefreshNPCState(self, canSyncClient=True, isReborn=False):
+        curNPC = self.__Instance
+        if curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
+            # 回合制怪走自己的刷属性规则
+            self.RefreshTurnfightNPCAttr()
+            return
+        
         self.RefreshNPCAttrState(canSyncClient, isReborn)
         
         self.RefreshNPCActionState()
 
-
+    def RefreshTurnfightNPCAttr(self):
+        curNPC = self.__Instance
+        lineupPlayerID = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_LineupPlayerID)
+        heroAttrDict = {}
+        if lineupPlayerID:
+            heroAttrDict.update({
+                                 ShareDefine.Def_Effect_Atk:500000000,
+                                 ShareDefine.Def_Effect_Def:50000000,
+                                 ShareDefine.Def_Effect_MaxHP:3000000000,
+                                 })
+        else:
+            npcDataEx = GetNPCDataEx(curNPC.GetNPCID())
+            if not npcDataEx:
+                return
+            heroAttrDict.update({
+                                 ShareDefine.Def_Effect_Atk:npcDataEx.GetAtk(),
+                                 ShareDefine.Def_Effect_Def:npcDataEx.GetDef(),
+                                 ShareDefine.Def_Effect_MaxHP:npcDataEx.GetMaxHP(),
+                                 })
+            
+        GameWorld.DebugLog("heroAttrDict: ID:%s,NPCID:%s,%s" % (curNPC.GetID(), curNPC.GetNPCID(), heroAttrDict))
+        # 重置属性状态
+        GameObj.ClearBattleEffect(curNPC)
+        curNPC.ResetNPCBattleState()
         
+        # 设置属性
+        curNPC.SetMinAtk(heroAttrDict.get(ShareDefine.Def_Effect_Atk, 1))
+        curNPC.SetMaxAtk(heroAttrDict.get(ShareDefine.Def_Effect_Atk, 1))
+        curNPC.SetDef(heroAttrDict.get(ShareDefine.Def_Effect_Def, 1))
+        GameObj.SetMaxHP(curNPC, heroAttrDict.get(ShareDefine.Def_Effect_MaxHP, 1))
+        
+        #GameObj.SetMissRate(curNPC, npcDataEx.GetMissRate())
+        #GameObj.SetMissDefRate(curNPC, npcDataEx.GetMissDefRate())
+        #GameObj.SetSuperHitRate(curNPC, npcDataEx.GetSuperHitRate())
+        #GameObj.SetSuperHitRateReduce(curNPC, npcDataEx.GetSuperHitRateReduce())
+        #GameObj.SetFaintRate(curNPC, npcDataEx.GetFaintRate())
+        #GameObj.SetFaintDefRate(curNPC, npcDataEx.GetFaintDefRate())
+        #GameObj.SetComboRate(curNPC, npcDataEx.GetComboRate())
+        #GameObj.SetComboDefRate(curNPC, npcDataEx.GetComboDefRate())
+        #GameObj.SetAtkBackRate(curNPC, npcDataEx.GetAtkBackRate())
+        #GameObj.SetAtkBackDefRate(curNPC, npcDataEx.GetAtkBackDefRate())
+        #GameObj.SetSuckHPPer(curNPC, npcDataEx.GetSuckHPPer())
+        #GameObj.SetSuckHPDefPer(curNPC, npcDataEx.GetSuckHPDefPer())
+        return
+    
     ## 刷新NPC属性
     #  @param self 类实例
     #  @param canSyncClient 是否通知客户端刷新信息(宠物)
@@ -6119,13 +6176,7 @@
 
 def NPCSpeedChangeNotify(curNPC, speed):
     ##通知NPC速度
-    sendPack = ChNetSendPack.tagObjInfoRefresh()
-    sendPack.Clear()
-    sendPack.ObjID = curNPC.GetID()
-    sendPack.ObjType = curNPC.GetGameObjType()
-    sendPack.RefreshType = IPY_GameWorld.CDBPlayerRefresh_Speed
-    sendPack.Value = speed
-    curNPC.NotifyAll(sendPack.GetBuffer(), sendPack.GetLength())
+    GameObj.NotifyObjInfoRefresh(curNPC, IPY_GameWorld.CDBPlayerRefresh_Speed, speed)
     return
 
 def UpdateNPCAttackCount(curPlayer, npcID, attackCount, maxCount=0):

--
Gitblit v1.8.0