| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # 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):
|
| | |
| | | Writer = hxp
|
| | | Releaser = hxp
|
| | | RegType = 0
|
| | | RegisterPackCount = 4
|
| | | RegisterPackCount = 5
|
| | |
|
| | | PacketCMD_1=0xA5
|
| | | PacketSubCMD_1=0x52
|
| | |
| | | PacketSubCMD_4=0x23
|
| | | PacketCallFunc_4=OnNPCShowEnd
|
| | |
|
| | | PacketCMD_5=0xB4
|
| | | PacketSubCMD_5=0x0C
|
| | | PacketCallFunc_5=OnSummonPriWoodPile
|
| | |
|
| | | ;资源找回
|
| | | [PlayerRecover]
|
| | | ScriptName = Player\PlayerRecover.py
|
| | |
| | | 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))
|
| | |
| | |
|
| | | 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)
|
| | |
| | | return "Robot"
|
| | | if obj.GetType() == ChConfig.ntHelpBattleRobot:
|
| | | return "HelpRobot"
|
| | | if obj.GetType() == ChConfig.ntPriWoodPilePVP:
|
| | | return "P"
|
| | |
|
| | | objType = obj.GetGameNPCObjType()
|
| | | if objType == IPY_GameWorld.gnotPet:
|
| | |
| | | #怪物的召唤兽,不考虑攻击模式问题
|
| | | 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
|
| | |
| | | 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为通用技能
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # 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):
|
| | |
| | | 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
|
| | |
| | |
|
| | | 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))
|
| | |
| | | # 详细描述: 设置屏幕周围NPC血量
|
| | | #
|
| | | #---------------------------------------------------------------------
|
| | | """Version = 2015-03-22 23:00"""
|
| | | #"""Version = 2015-03-22 23:00"""
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | |
|
| | | import IpyGameDataPY
|
| | | import IPY_GameWorld
|
| | | import GameWorld
|
| | | import ChConfig
|
| | |
| | | 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
|
| | |
| | | #逻辑实现
|
| | | ## 在身边刷召唤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)
|
| | | #初始化
|
| | |
| | |
|
| | | #玩家召唤兽列表添加召唤兽,召唤兽添加主人
|
| | | summonNPC.Reborn(resultPos.GetPosX(), resultPos.GetPosY())
|
| | | return
|
| | |
|
| | |
|
| | |
|
| | |
| | | import ShareDefine
|
| | | import ChConfig
|
| | | import IPY_GameWorld
|
| | | import IpyGameDataPY
|
| | |
|
| | | # 关于血量的函数这里只包装最简单的超DWORD处理
|
| | |
|
| | |
| | | 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)
|
New file |
| | |
| | | #!/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
|
| | |
|
| | |
| | |
|
| | | 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
|