From 07668b75bca23b706d1a06c9cc7591caf5b163fd Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 20 一月 2025 19:10:03 +0800
Subject: [PATCH] 10263 【越南】【英文】【BT】【砍树】后端支持NPC仿真实玩家战斗和快速战斗(优化镜像玩家移动)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/MirrorAttack.py |   74 ++++++++++++++++++++++++++----------
 1 files changed, 53 insertions(+), 21 deletions(-)

diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/MirrorAttack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/MirrorAttack.py
index acd08bd..5f12948 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/MirrorAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/MirrorAttack.py
@@ -43,8 +43,10 @@
 import GameObj
 
 import time
+import math
 
 Def_StateTimeList = [3, 60, 10] # 默认阶段时长,秒
+Mirror_StartMoveTick = "Mirror_StartMoveTick"
 
 class MirrorBattle():
     ## 某场战斗
@@ -705,7 +707,7 @@
     isOK = False
     actionObj = PlayerState.__GetCanAttack_ObjDetel(curPlayer, tick)
     if actionObj:
-        isOK = PlayerAttack(curPlayer, actionObj, tick, autoUseSkillList)
+        isOK = PlayerAttack(curPlayer, actionObj, tick, autoUseSkillList, battle.isQuick)
         
     if not isOK:
         curFaction = curPlayer.GetFaction()
@@ -716,7 +718,7 @@
             if actionObj and actionObj.GetID() == batPlayerID:
                 continue
             tagObj = playerMgr.FindPlayerByID(batPlayerID)
-            isOK = PlayerAttack(curPlayer, tagObj, tick, autoUseSkillList)
+            isOK = PlayerAttack(curPlayer, tagObj, tick, autoUseSkillList, battle.isQuick)
             if isOK:
                 break
             
@@ -726,7 +728,7 @@
     
     return
 
-def PlayerAttack(curPlayer, tagObj, tick, autoUseSkillList):
+def PlayerAttack(curPlayer, tagObj, tick, autoUseSkillList, isQuick=False):
     ## 玩家攻击, 参考技能使用 #def UseSkillEx(index, clientData, tick):
     if not tagObj or GameObj.GetHP(tagObj) <= 0:
         return
@@ -760,7 +762,7 @@
         if SkillCommon.RefreshSkillRemainTime(curSkill, tick) != 0:
             continue
         
-        if not AttackCommon.CheckPlayerAttackDist(curPlayer, tagObj, curSkill):
+        if not AttackCommon.CheckPlayerAttackDist(curPlayer, tagObj, curSkill, True):
             needMoveto = True
             continue
         
@@ -784,18 +786,20 @@
         curPlayer.SetAttackTick(tick)
     else:
         if needMoveto:
-            MoveToObj(curPlayer, tagObj, tick)
+            MoveToObj(curPlayer, tagObj, tick, isQuick)
             return
         
+    curPlayer.SetDict(Mirror_StartMoveTick, 0)
     return useSkillResult
 
-def MoveToObj(curPlayer, tagObj, tick):
+def MoveToObj(curPlayer, tagObj, tick, isQuick=False):
     #不可移动行为状态, 服务端限制
     if not OperControlManager.IsObjCanDoAction(curPlayer,
                                                ChConfig.Def_Obj_ActState_ServerAct,
                                                IPY_GameWorld.oalMove):
         return
     
+    curPosX, curPosY = curPlayer.GetPosX(), curPlayer.GetPosX()
     destX = tagObj.GetPosX()
     destY = tagObj.GetPosY()
     # 缩小两格子用于前方一小片区域
@@ -803,27 +807,53 @@
     moveDestX = resultPos.GetPosX()
     moveDestY = resultPos.GetPosY()
     
-    if (tick - curPlayer.GetDictByKey("MoveTick")) < 1000:
-        # .Move( 接口调用太快会导致移动时间不够长(不足一格)导致无法移动 或者移动过慢问题
-        # SetDestPos 调用会导致反向移动偏快
-        #curPlayer.SetDestPos(moveDestX, moveDestY)
+    if isQuick:
+        curPlayer.ChangePos(moveDestX, moveDestY)
+        #GameWorld.DebugLog("---直接设置坐标: %s,%s to %s,%s, %s,%s" % (curPosX, curPosY, moveDestX, moveDestY, curPlayer.GetPosX(), curPlayer.GetPosY()), curPlayer.GetID())
         return
-    curPlayer.SetDict("MoveTick", tick)
-    #return curPlayer.Move(moveDestX, moveDestY)
     
-    # 执行一次重置位置,避免快速发包导致无法移动
-    curPlayer.ChangePos(moveDestX, moveDestY)
+    startMoveTick = curPlayer.GetDictByKey(Mirror_StartMoveTick)
+    if not startMoveTick:
+        curPlayer.SetDict(Mirror_StartMoveTick, tick)
+        #GameWorld.DebugLog("---设置开始移动: %s,%s to %s,%s, tick=%s" % (curPosX, curPosY, moveDestX, moveDestY, tick), curPlayer.GetID())
+        return
+    
+    speed = curPlayer.GetSpeed()
+    if not speed:
+        return
+    
+    interval = tick - startMoveTick
+    moveDist = interval / float(speed)
+    #GameWorld.DebugLog("---计算位移: moveDist=%s,speed=%s,interval=%s(%s-%s)" % (moveDist, speed, interval, tick, startMoveTick), curPlayer.GetID())
+    if moveDist <= 0:
+        return
+    
+    m_DestPosX, m_DestPosY = moveDestX, moveDestY
+    m_StartPosX, m_StartPosY = curPosX, curPosY
+    m_DestDist = GameWorld.GetDistEx(m_StartPosX, m_StartPosY, m_DestPosX, m_DestPosY, False)
+    updPosX = int(math.ceil(moveDist * (m_DestPosX - m_StartPosX) / m_DestDist + m_StartPosX))
+    updPosY = int(math.ceil(moveDist * (m_DestPosY - m_StartPosY) / m_DestDist + m_StartPosY))
+    
+    cDist = GameWorld.GetDistEx(curPosX, curPosY, updPosX, updPosY, False)
+    if cDist <= 1:
+        #GameWorld.DebugLog("--------------------暂不移动: cDist=%s,updPos(%s,%s),curPos(%s,%s),m_DestPos(%s,%s),m_DestDist=%s" 
+        #                   % (cDist, updPosX, updPosY, curPosX, curPosY, moveDestX, moveDestY, m_DestDist), curPlayer.GetID())
+        return
+    #GameWorld.DebugLog("--------------------更新坐标: cDist=%s,updPos(%s,%s),curPos(%s,%s),m_DestPos(%s,%s),m_DestDist=%s" 
+    #                   % (cDist, updPosX, updPosY, curPosX, curPosY, moveDestX, moveDestY, m_DestDist), curPlayer.GetID())
+    curPlayer.ChangePos(updPosX, updPosY)
+    curPlayer.SetDict(Mirror_StartMoveTick, tick)
     
     sendPack = ChNetSendPack.tagObjMove()
     sendPack.Clear()
     sendPack.ObjID = curPlayer.GetID()
-    sendPack.ObjType = IPY_GameWorld.gotNPC
-    sendPack.MoveType = IPY_GameWorld.gotPlayer
-    sendPack.DestPosX = moveDestX
-    sendPack.DestPosY = moveDestY
-    sendPack.Speed = curPlayer.GetSpeed()
-    sendPack.StartPosX = curPlayer.GetPosX()
-    sendPack.StartPosY = curPlayer.GetPosY()
+    sendPack.ObjType = curPlayer.GetGameObjType()
+    sendPack.MoveType = IPY_GameWorld.mtNormal
+    sendPack.DestPosX = updPosX
+    sendPack.DestPosY = updPosY
+    sendPack.Speed = speed
+    sendPack.StartPosX = curPosX
+    sendPack.StartPosY = curPosY
     curPlayer.NotifyAll(sendPack.GetBuffer(), sendPack.GetLength())
     return
 
@@ -852,6 +882,7 @@
     playerMgr = GameWorld.GetMapCopyPlayerManager()
     perLoopTick = 100 # 每次循环视为已过毫秒
     maxLoopCount = battle.stateTickRemain / perLoopTick # 循环次数上限
+    GameWorld.DebugLog("------------------------ 镜像PK快速结算 ------------------------", battleID)
     GameWorld.DebugLog("镜像PK快速结算: isLogout=%s,maxLoopCount=%s,tick=%s,stateTickRemain=%s" 
                        % (isLogout, maxLoopCount, tick, battle.stateTickRemain), battleID)
     
@@ -976,6 +1007,7 @@
         player = playerMgr.FindPlayerByID(playerID)
         if not player:
             continue
+        player.StopMove()
         realPlayerID = player.GetRealPlayerID()
         hp = GameObj.GetHP(player)
         hpMax = GameObj.GetMaxHP(player)

--
Gitblit v1.8.0