hxp
2019-04-29 fba7745533989fc514ce7a8e9edc8017abd2d69e
6661 【后端】【2.0】战斗需要木桩
12个文件已修改
1个文件已添加
307 ■■■■ 已修改文件
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_SummonNPC.py 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/KillScreenNPC.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintNPCInfo.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SetNPCHP.py 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SummonNPC.py 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_202.py 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
@@ -14517,6 +14517,62 @@
#------------------------------------------------------
# B4 0C 召唤私有专属木桩怪 #tagCMSummonPriWoodPile
class  tagCMSummonPriWoodPile(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("NPCID", c_int),
                  ("Count", c_ubyte),    #默认1个,最多5个
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xB4
        self.SubCmd = 0x0C
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.Cmd = 0xB4
        self.SubCmd = 0x0C
        self.NPCID = 0
        self.Count = 0
        return
    def GetLength(self):
        return sizeof(tagCMSummonPriWoodPile)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B4 0C 召唤私有专属木桩怪 //tagCMSummonPriWoodPile:
                                Cmd:%s,
                                SubCmd:%s,
                                NPCID:%d,
                                Count:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.NPCID,
                                self.Count
                                )
        return DumpString
m_NAtagCMSummonPriWoodPile=tagCMSummonPriWoodPile()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMSummonPriWoodPile.Cmd,m_NAtagCMSummonPriWoodPile.SubCmd))] = m_NAtagCMSummonPriWoodPile
#------------------------------------------------------
#B4 06 战斗移动 # tagCMFightMove
class  tagCMFightMove(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -743,7 +743,7 @@
Writer = hxp
Releaser = hxp
RegType = 0
RegisterPackCount = 4
RegisterPackCount = 5
PacketCMD_1=0xA5
PacketSubCMD_1=0x52
@@ -761,6 +761,10 @@
PacketSubCMD_4=0x23
PacketCallFunc_4=OnNPCShowEnd
PacketCMD_5=0xB4
PacketSubCMD_5=0x0C
PacketCallFunc_5=OnSummonPriWoodPile
;资源找回
[PlayerRecover]
ScriptName = Player\PlayerRecover.py
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
@@ -1772,11 +1772,13 @@
            remainHP = min(dHP, max(GameObj.GetMaxHP(defObj)/2, remainHP)) # 助战机器人剩余血量不能少于一半
            GameObj.SetHP(defObj, remainHP)
        
        elif defObj.GetType() == ChConfig.ntMonsterTime:
            UpdateTimeMonsterHP(defObj, tick)
        else:
            #防守方是怪物NPC,只扣其血
            npcID = defObj.GetNPCID()
            timeLostHPIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCTimeLostHP", npcID)
            if timeLostHPIpyData:
                UpdateTimeMonsterHP(defObj, timeLostHPIpyData, tick)
            else:
            GameObj.SetHP(defObj, remainHP)
    else:
        GameWorld.ErrLog('计算伤血值时,防守方类型错误:defObjType = %s' % (defObjType))
@@ -1799,16 +1801,11 @@
    
    return resultHurtType
def UpdateTimeMonsterHP(curNPC, tick):
def UpdateTimeMonsterHP(curNPC, ipyData, tick):
    '''
    NPC总血量 = 单人每秒掉血量*理论击杀所需时间
         掉血值 = 单人每秒掉血量+min(当前人数, 最大人数)*附加掉血量
    '''
    npcID = curNPC.GetNPCID()
    ipyData = IpyGameDataPY.GetIpyGameData("NPCTimeLostHP", npcID)
    if not ipyData:
        return
        
    lastLostHPTick = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_TimeLostHPTick)
    curNPC.SetDict(ChConfig.Def_NPC_Dict_TimeLostHPTick, tick)
@@ -2372,6 +2369,8 @@
            return "Robot"
        if obj.GetType() == ChConfig.ntHelpBattleRobot:
            return "HelpRobot"
        if obj.GetType() == ChConfig.ntPriWoodPilePVP:
            return "P"
        
    objType = obj.GetGameNPCObjType()
    if objType == IPY_GameWorld.gnotPet:
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_SummonNPC.py
@@ -70,6 +70,12 @@
        #怪物的召唤兽,不考虑攻击模式问题
        return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
    
    #私有木桩只能自己打自己的
    if curTagSummonNPC.GetType() in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:
        if not GameWorld.IsSameObj(curPlayer, curTagPlayer):
            return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
        return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
    #自己的召唤兽,不能攻击
    if GameWorld.IsSameObj(curPlayer, curTagPlayer) :
        return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -5010,9 +5010,11 @@
ntDestructible, #场景内可破坏的 19
ntHelpBattleRobot, #助战机器人 20
ntRobot, #机器人21
ntMonsterTime, #按时间掉血的怪物 22
ntMonsterTime, #按时间掉血的怪物 22 废弃,以是否有配置在时间掉血怪物表为准
ntPriWoodPilePVE, #专属私有木桩 - PVE 23
ntPriWoodPilePVP, #专属私有木桩 - PVP 24
ntMax
) = range(24)
) = range(26)
(Def_SkillFuncType_Common, #0为通用技能
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -14517,6 +14517,62 @@
#------------------------------------------------------
# B4 0C 召唤私有专属木桩怪 #tagCMSummonPriWoodPile
class  tagCMSummonPriWoodPile(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("NPCID", c_int),
                  ("Count", c_ubyte),    #默认1个,最多5个
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xB4
        self.SubCmd = 0x0C
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.Cmd = 0xB4
        self.SubCmd = 0x0C
        self.NPCID = 0
        self.Count = 0
        return
    def GetLength(self):
        return sizeof(tagCMSummonPriWoodPile)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B4 0C 召唤私有专属木桩怪 //tagCMSummonPriWoodPile:
                                Cmd:%s,
                                SubCmd:%s,
                                NPCID:%d,
                                Count:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.NPCID,
                                self.Count
                                )
        return DumpString
m_NAtagCMSummonPriWoodPile=tagCMSummonPriWoodPile()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMSummonPriWoodPile.Cmd,m_NAtagCMSummonPriWoodPile.SubCmd))] = m_NAtagCMSummonPriWoodPile
#------------------------------------------------------
#B4 06 战斗移动 # tagCMFightMove
class  tagCMFightMove(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/KillScreenNPC.py
@@ -83,7 +83,7 @@
        return
    if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie:
        return
    if curNPC.GetType() not in [IPY_GameWorld.ntMonster, ChConfig.ntMonsterTime]:
    if curNPC.GetType() not in [IPY_GameWorld.ntMonster, ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:
        return
    if not curNPC.GetVisible():
        return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintNPCInfo.py
@@ -50,7 +50,7 @@
    
    npcID = curNPC.GetNPCID()
    GameWorld.DebugAnswer(curPlayer, "-----------------------%s" % random.randint(0, 100))
    GameWorld.DebugAnswer(curPlayer, "ObjID: %s, NPCID: %s, %s" % (curNPC.GetID(), npcID, curNPC.GetName()))
    GameWorld.DebugAnswer(curPlayer, "ObjID: %s, NPCID: %s, %s, Type: %s" % (curNPC.GetID(), npcID, curNPC.GetName(), curNPC.GetType()))
    if FamilyRobBoss.IsHorsePetRobBoss(npcID):
        strengthenPlayerCnt = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_HorsePetRobBossPlayerCount)
        GameWorld.DebugAnswer(curPlayer, "表等级: %s, 成长等级: %s, 参与人数: %s" % (curNPC.GetLV(), curNPC.GetCurLV(), strengthenPlayerCnt))
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SetNPCHP.py
@@ -14,10 +14,10 @@
# 详细描述: 设置屏幕周围NPC血量
#
#---------------------------------------------------------------------
"""Version = 2015-03-22 23:00"""
#"""Version = 2015-03-22 23:00"""
#---------------------------------------------------------------------
import IpyGameDataPY
import IPY_GameWorld
import GameWorld
import ChConfig
@@ -75,7 +75,9 @@
    return
def __GMSetNPCHP(curPlayer, curNPC, setHP):
    GameObj.SetHP(curNPC, setHP)
    npcID = curNPC.GetNPCID()
    isByTime = True if IpyGameDataPY.GetIpyGameDataNotLog("NPCTimeLostHP", npcID) else False
    GameObj.SetHP(curNPC, setHP, isByTime=isByTime)
    curNPC.Notify_HPEx()
    GameWorld.DebugAnswer(curPlayer, "SetNPCHP ID=%s(%s),HP=%s" % (curNPC.GetID(), curNPC.GetNPCID(), setHP))
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SummonNPC.py
@@ -21,40 +21,34 @@
#逻辑实现
## 在身边刷召唤NPC <NPCID> [数量] 默认数量:1
#  @param curPlayer 当前玩家
#  @param list 参数列表 [tagID, NPCCount]
#  @param paramList 参数列表 [tagID, NPCCount]
#  @return None
#  @remarks 函数详细说明.
def OnExec(curPlayer, list):
#===============================================================================
#    #检测当前玩家是否有权限
#    #if
#    #第一阶段不处理
#===============================================================================
def OnExec(curPlayer, paramList):
    #输入命令格式错误
    if len(list)<1 or len(list)>2:
    if not paramList or len(paramList) > 2:
        GameWorld.DebugAnswer(curPlayer, "SummonNPC npcID 个数")
        return
    #NPC对象ID
    tagID=list[0]
    npcID = paramList[0]
    npcCount = max(paramList[1] if len(paramList) > 1 else 1, 1)
    npcData = GameWorld.GetGameData().FindNPCDataByID(npcID)
    
    if not GameWorld.GetGameData().FindNPCDataByID(tagID):
    if not npcData:
        return
        
    npcType = npcData.GetType()
    if npcType in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:
        NPCCommon.SummonPriWoodPile(curPlayer, npcID, npcCount)
        return
    
    #NPC刷新数量
    if len(list)==1:
        #默认数量1
        NPCCount=1
    else:
        #GM输入的数量
        NPCCount=list[1]
    for i in range(0,NPCCount):
    for _ in range(npcCount):
        #在玩家周围选择一个无玩家的点
        resultPos=GameMap.GetEmptyPlaceInArea(curPlayer.GetPosX(),curPlayer.GetPosY(),6)
        #生成NPC
        summonNPC = curPlayer.SummonNewNPC()
        summonNPC.SetNPCTypeID(tagID)
        summonNPC.SetNPCTypeID(npcID)
        summonNPC.SetAIType(200)
        summonNPC.GetNPCAngry().Init(ChConfig.Def_SummonNPC_Angry_Count)
        #初始化
@@ -63,6 +57,7 @@
        
        #玩家召唤兽列表添加召唤兽,召唤兽添加主人
        summonNPC.Reborn(resultPos.GetPosX(), resultPos.GetPosY())
    return
        
        
    
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py
@@ -15,6 +15,7 @@
import ShareDefine
import ChConfig
import IPY_GameWorld
import IpyGameDataPY
# 关于血量的函数这里只包装最简单的超DWORD处理
@@ -47,7 +48,9 @@
    if gameObj.GetGameObjType() == IPY_GameWorld.gotPlayer:
        gameObj.SetHP(value, isNotify)
    else:
        if gameObj.GetType() == ChConfig.ntMonsterTime and not isByTime and value not in [GetMaxHP(gameObj), 0]:
        if gameObj.GetGameObjType() == IPY_GameWorld.gotNPC:
            npcID = gameObj.GetNPCID()
            if IpyGameDataPY.GetIpyGameDataNotLog("NPCTimeLostHP", npcID) and not isByTime and value not in [GetMaxHP(gameObj), 0]:
            #GameWorld.DebugLog("不能设置按时间掉血的怪物血量! id=%s,npciD=%s,value=%s,isByTime=%s" % (gameObj.GetID(), gameObj.GetNPCID(), value, isByTime))
            return
        gameObj.SetHPEx(value/ShareDefine.Def_PerPointValue)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_202.py
New file
@@ -0,0 +1,45 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package NPCAI.AIType_202
#
# @todo:专属木桩
# @author hxp
# @date 2019-04-29
# @version 1.0
#
# 详细描述: 跟随主人
#
#-------------------------------------------------------------------------------
#"""Version = 2019-04-29 17:00"""
#-------------------------------------------------------------------------------
import IPY_GameWorld
import NPCCommon
import GameWorld
import GameMap
##AI逻辑处理
#@param curNPC NPC实例
#@param tick 时间戳
#@return 返回值无意义
def ProcessAI(curNPC, tick):
    npcControl = NPCCommon.NPCControl(curNPC)
    if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie:
        #NPC死亡, 进入死亡倒计时
        if npcControl.DieTick(tick) == 0:
            return
    #刷新自己的Buff
    npcControl.RefreshBuffState(tick)
    owner = NPCCommon.GetNpcObjOwnerDetail(curNPC)
    if GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(), owner.GetPosX(), owner.GetPosY()) > 5:
        resetPos = GameMap.GetEmptyPlaceInArea(owner.GetPosX(), owner.GetPosY(), 2)
        curNPC.ResetPos(resetPos.GetPosX(), resetPos.GetPosY())
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -1940,6 +1940,67 @@
        
    return
#// B4 0C 召唤私有专属木桩怪 #tagCMSummonPriWoodPile
#
#struct    tagCMSummonPriWoodPile
#{
#    tagHead        Head;
#    DWORD        NPCID;
#    BYTE        Count;    //默认1个,最多5个
#};
def OnSummonPriWoodPile(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    npcID = clientData.NPCID
    count = clientData.Count
    SummonPriWoodPile(curPlayer, npcID, count)
    return
def SummonPriWoodPile(curPlayer, npcID, count):
    ''' 召唤私有专属木桩怪
    '''
    maxCount = 5
    nowCount = 0
    # 只允许存在一个私有木桩
    indexList = range(curPlayer.GetSummonCount())
    for index in indexList[::-1]:
        summonNPC = curPlayer.GetSummonNPCAt(index)
        if not summonNPC:
            continue
        npcType = summonNPC.GetType()
        if npcType not in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:
            continue
        if nowCount >= maxCount or summonNPC.GetNPCID() != npcID:
            SetDeadEx(summonNPC)
        else:
            nowCount += 1
    summonCount = min(count, maxCount - nowCount)
    #GameWorld.DebugLog("召唤: count=%s,maxCount=%s,nowCount=%s,summonCount=%s"
    #                   % (count, maxCount, nowCount, summonCount))
    if summonCount <= 0:
        return
    for _ in xrange(summonCount):
        summonNPC = curPlayer.SummonNewNPC()
        #设置召唤兽基础信息
        summonNPC.SetNPCTypeID(npcID)
        #初始化
        InitNPC(summonNPC)
        #玩家召唤兽列表添加召唤兽,召唤兽添加主人
        summonNPC.SetOwner(curPlayer)
        summonNPC.SetDict(ChConfig.Def_NPC_Dict_SummonMapNPCPlayerID, curPlayer.GetPlayerID())
        #将召唤兽召唤出来
        #玩家周围随机出生点
        #技能召唤坐标 ChConfig.Def_SummonAppearDist
        summonPos = GameMap.GetEmptyPlaceInArea(curPlayer.GetPosX(), curPlayer.GetPosY(), 3)
        summonNPC.Reborn(summonPos.GetPosX(), summonPos.GetPosY())
    return
## 设置npc死亡及自身处理(请不要将游戏逻辑加在此函数中)
#  @param curNPC:npc实例
#  @return