129 【战斗】战斗系统-服务端(优化战斗武将跟NPC独立处理;去除程序无技能普攻,增加反击普攻;新增回合主动普攻技能功能类型23;)
| | |
| | | DWORD _HeroID; //英雄ID
|
| | | BYTE Country; // 国家
|
| | | BYTE Quality; // 品质
|
| | | list SkinNPCIDList; // 皮肤NPCID列表
|
| | | BYTE AtkDistType; //远近类型;1-近战;2-远程
|
| | | list SkinIDList; // 皮肤ID列表
|
| | | DWORD NormalSkillID; //普攻技能ID
|
| | | DWORD AngerSkillID; //怒气技能ID
|
| | | WORD AtkInheritPer; //攻击继承
|
| | |
| | | list AttrValueList; // 属性值列表
|
| | | };
|
| | |
|
| | | //武将皮肤表
|
| | | //皮肤表
|
| | | struct HeroSkin
|
| | | {
|
| | | DWORD _SkinNPCID; //皮肤NPCID
|
| | | DWORD _SkinID; //皮肤NPCID
|
| | | list WearAttrIDList; // 穿戴属性ID列表
|
| | | list WearAttrValueList; // 穿戴属性值列表
|
| | | list AllBatAttrIDList; // 全体上阵属性ID列表
|
| | |
| | | DWORD _NPCID; //NPCID
|
| | | BYTE FightPowerLackAtkLimit; //战力不足限制攻击
|
| | | DWORD SuppressFightPower; //推荐/压制战力
|
| | | BYTE AtkDictType; //远近类型;1-近战;2-远程
|
| | | BYTE AtkDistType; //远近类型;1-近战;2-远程
|
| | | DWORD Atk; //攻击力
|
| | | DWORD Def; //防御值
|
| | | DWORD MaxHP; //最大生命值,可超过20E
|
| | |
| | | #NPC读表取
|
| | | return attack.GetHurtType()
|
| | |
|
| | | def GetAtkDistType(curObj):
|
| | | ## 获取是近战还是远程,默认近战
|
| | | if curObj.GetGameObjType() != IPY_GameWorld.gotNPC:
|
| | | return ChConfig.AtkDistType_Short
|
| | | |
| | | playerID = curObj.GetDictByKey(ChConfig.Def_Obj_Dict_LineupPlayerID)
|
| | | if not playerID:
|
| | | return ChConfig.AtkDistType_Short
|
| | | |
| | | heroID = curObj.GetDictByKey(ChConfig.Def_Obj_Dict_HeroID)
|
| | | if heroID:
|
| | | heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
|
| | | if heroIpyData:
|
| | | return heroIpyData.GetAtkDistType()
|
| | | |
| | | npcID = curObj.GetNPCID()
|
| | | npcDataEx = NPCCommon.GetNPCDataEx(npcID)
|
| | | if npcDataEx:
|
| | | return npcDataEx.GetAtkDistType()
|
| | | |
| | | return ChConfig.AtkDistType_Short
|
| | |
|
| | | ## 输入基础数值,返回增强后的值 - 技能加强
|
| | | # @param value 基础值
|
| | | # @param skill 技能
|
| | |
| | | return
|
| | |
|
| | | if curSkill and curSkill.GetFuncType() not in [ChConfig.Def_SkillFuncType_FbSkill,
|
| | | ChConfig.Def_SkillFuncType_NormalAttack]:
|
| | | ChConfig.Def_SkillFuncType_TurnNormaAttack]:
|
| | | return
|
| | |
|
| | | if attacker.GetDictByKey(ChConfig.Def_PlayerKey_FirstDefender):
|
| | |
| | |
|
| | | # --- 新增普通攻击的数值和技能攻击的数值,根据类型各自计算
|
| | | if atkObjType == IPY_GameWorld.gotPlayer:
|
| | | if not curSkill or curSkill.GetFuncType() == ChConfig.Def_SkillFuncType_NormalAttack:
|
| | | if not curSkill or curSkill.GetFuncType() == ChConfig.Def_SkillFuncType_TurnNormaAttack:
|
| | | atkSkillPer += PlayerControl.GetNormalHurtPer(atkObj)
|
| | | atkSkillValue += PlayerControl.GetNormalHurt(atkObj)
|
| | | elif curSkill.GetFuncType() in [ChConfig.Def_SkillFuncType_FbSkill, ChConfig.Def_SkillFuncType_FbPassiveSkill]:
|
| | |
| | | elif not curSkill:
|
| | | hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("HurtFormula", 3))
|
| | | GameWorld.DebugLog(" 普攻伤害=%s" % (hurtValue))
|
| | | elif SkillCommon.isNormalAtkSkill(curSkill):
|
| | | elif SkillCommon.isTurnNormalAtkSkill(curSkill):
|
| | | hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("HurtFormula", 1))
|
| | | GameWorld.DebugLog(" 普攻技能伤害=%s" % (hurtValue))
|
| | | elif SkillCommon.isXPSkill(curSkill):
|
| | |
| | | if not curSkill or (curSkill.GetSkillType() == ChConfig.Def_SkillType_Atk and\
|
| | | curSkill.GetFuncType() in [ChConfig.Def_SkillFuncType_FbSkill,
|
| | | ChConfig.Def_SkillFuncType_PetSkill,
|
| | | ChConfig.Def_SkillFuncType_NormalAttack]):
|
| | | ChConfig.Def_SkillFuncType_NormalAttack,
|
| | | ChConfig.Def_SkillFuncType_TurnNormaAttack]):
|
| | | # 攻击减层级 优先处理,因为同个技能触发buff后,会再处理层级,导致立即减层级
|
| | | PassiveBuffEffMng.OnPassiveBuffTrigger(attacker, defender, curSkill, ChConfig.TriggerType_Buff_AttackSubLayer, tick)
|
| | |
|
| | |
| | | import ItemControler
|
| | | import SkillCommon
|
| | | import SkillShell
|
| | | import BaseAttack
|
| | | import AttackCommon
|
| | |
|
| | | import random
|
| | | import time
|
| | | import json
|
| | |
|
| | | FighterNPCID = 100 # 战斗NPCID,仅后端用,除怪物外,所有玩家武将均使用该NPCID
|
| | | PosNumMax = 10 # 最大站位编号
|
| | | ActionNumStart = -1 # 起始行动位置编号,一般是从1开始,如果有加主公、红颜等则扣除相应位置值,如从0或-1开始
|
| | |
|
| | |
| | | tfObj = ChPyNetSendPack.tagSCTurnFightObj()
|
| | | tfObj.ObjID = curNPC.GetID()
|
| | | tfObj.NPCID = curNPC.GetNPCID()
|
| | | tfObj.HeroID = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_HeroID)
|
| | | tfObj.SkinID = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_SkinID)
|
| | | tfObj.HP = curNPC.GetHP()
|
| | | tfObj.HPEx = curNPC.GetHPEx()
|
| | | tfObj.MaxHP = curNPC.GetMaxHP()
|
| | |
| | | heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
|
| | | if not heroIpyData:
|
| | | continue
|
| | | |
| | | npcID = heroIpyData.GetSkinNPCIDList()[0]
|
| | | skinIDList = heroIpyData.GetSkinIDList()
|
| | | skinIndex = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroSkin)
|
| | | if skinIndex < 0 or skinIndex >= len(skinIDList):
|
| | | continue
|
| | | skinID = skinIDList[skinIndex]
|
| | | heroDict[str(posNum)] = {
|
| | | "ID":heroID,
|
| | | "HeroID":heroID,
|
| | | "SkinID":skinID,
|
| | | "Data":heroItem.GetUserData(),
|
| | | "NPCID":npcID
|
| | | }
|
| | |
|
| | | heroCount += 1
|
| | |
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | |
|
| | | initXP = IpyGameDataPY.GetFuncCfg("AngerXP", 1)
|
| | | baseAtkSkillIDList = IpyGameDataPY.GetFuncEvalCfg("ParryCfg", 3)
|
| | | tfMgr = GetTurnFightMgr()
|
| | | space = 3
|
| | | for posNumKey, heroInfo in heroDict.items():
|
| | | posNum = int(posNumKey)
|
| | |
|
| | | heroID, skinID = 0, 0
|
| | | baseAtkSkillID = 0 # 基础普攻ID
|
| | | skillIDList = []
|
| | | if lineupPlayerID:
|
| | | heroID = heroInfo.get("ID", 0)
|
| | | npcID = heroInfo.get("NPCID", 0)
|
| | | heroID = heroInfo.get("HeroID", 0)
|
| | | skinID = heroInfo.get("SkinID", 0)
|
| | | npcID = FighterNPCID
|
| | | heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
|
| | | if not heroIpyData:
|
| | | continue
|
| | | normalSkillID = heroIpyData.GetNormalSkillID()
|
| | | angerSkillID = heroIpyData.GetAngerSkillID()
|
| | | skillIDList += [normalSkillID, angerSkillID]
|
| | | atkDistType = heroIpyData.GetAtkDistType()
|
| | | else:
|
| | | npcID = heroInfo.get("NPCID", 0)
|
| | | npcDataEx = NPCCommon.GetNPCDataEx(npcID)
|
| | | if not npcDataEx:
|
| | | continue
|
| | | skillIDList += npcDataEx.GetSkillIDList()
|
| | | atkDistType = npcDataEx.GetAtkDistType()
|
| | |
|
| | | if not npcID:
|
| | | continue
|
| | |
| | | curSummon.SetVisible(True)
|
| | | curSummon.SetDict(ChConfig.Def_Obj_Dict_TurnFightPosInfo, num * 100 + posNum)
|
| | | curSummon.SetDict(ChConfig.Def_Obj_Dict_LineupPlayerID, lineupPlayerID)
|
| | | curSummon.SetDict(ChConfig.Def_Obj_Dict_HeroID, heroID)
|
| | | curSummon.SetDict(ChConfig.Def_Obj_Dict_SkinID, skinID)
|
| | | GameObj.SetFaction(curSummon, faction)
|
| | | GameObj.SetXP(curSummon, initXP, False)
|
| | | |
| | | if atkDistType == ChConfig.AtkDistType_Short:
|
| | | baseAtkSkillID = baseAtkSkillIDList[0] if len(baseAtkSkillIDList) > 0 else 0
|
| | | elif atkDistType == ChConfig.AtkDistType_Long:
|
| | | baseAtkSkillID = baseAtkSkillIDList[1] if len(baseAtkSkillIDList) > 1 else 0
|
| | |
|
| | | skillManager = curSummon.GetSkillManager()
|
| | | #有指定的技能,重新学习
|
| | |
| | | skillManager.ResetSkill()
|
| | | for skillID in skillIDList:
|
| | | skillManager.LVUPSkillByID(skillID)
|
| | | if baseAtkSkillID:
|
| | | skillManager.LVUPSkillByID(baseAtkSkillID)
|
| | |
|
| | | rebornX = posX - space + (faction - 1) * space * 3 + ((posNum - 1) / 3 * space * 2 * (-1 if faction == 1 else 1))
|
| | | rebornY = posY + (posNum - 1) % 3 * space
|
| | | #GameWorld.DebugLog("Reborn ID:%s, faction:%s,posNum=%s, (%s,%s), %s" % (curSummon.GetID(), faction, posNum, rebornX, rebornY, skillIDList))
|
| | | GameWorld.DebugLog("SummonNPC ID:%s,faction:%s,num=%s,posNum=%s,baseAtkSkillID=%s,%s" % (curSummon.GetID(), faction, num, posNum, baseAtkSkillID, skillIDList))
|
| | | curSummon.Reborn(rebornX, rebornY, False)
|
| | | NPCCommon.NPCControl(curSummon).DoNPCRebornCommLogic(tick)
|
| | |
|
| | |
| | | objName = gameObj.GetName()
|
| | | faction = GameObj.GetFaction(gameObj)
|
| | | posInfo = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo)
|
| | | npcID = gameObj.GetNPCID()
|
| | | return "%s%s %s[%s-%s]" % ("A" if faction == Def_FactionA else "B", posInfo, objName, gameObj.GetID(), npcID)
|
| | | heroID = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_HeroID)
|
| | | if not heroID:
|
| | | heroID = gameObj.GetNPCID()
|
| | | return "%s%s %s[%s-%s]" % ("A" if faction == Def_FactionA else "B", posInfo, objName, gameObj.GetID(), heroID)
|
| | |
|
| | | def EntryLogic(turnFight):
|
| | | ## 执行进场逻辑
|
| | |
| | | ## 攻击方增加的XP值根据主动普攻技能获得
|
| | | if not curSkill:
|
| | | return 0
|
| | | if not SkillCommon.isNormalAtkSkill(curSkill):
|
| | | if not SkillCommon.isTurnNormalAtkSkill(curSkill):
|
| | | return 0
|
| | | return IpyGameDataPY.GetFuncCfg("AngerXP", 3)
|
| | |
|
| | |
| | | if turnBattleType == ChConfig.TurnBattleType_AtkBack:
|
| | | if not tagObj:
|
| | | return
|
| | | atkOK = BaseAttack.Attack(curNPC, tagObj, None, tick) # 反击为单体普攻
|
| | | skillManager = curNPC.GetSkillManager()
|
| | | for index in range(0, skillManager.GetSkillCount()):
|
| | | skill = skillManager.GetSkillByIndex(index)
|
| | | #已经到尾部了
|
| | | if not skill or skill.GetSkillTypeID() == 0:
|
| | | break
|
| | | if skill.GetFuncType() == ChConfig.Def_SkillFuncType_NormalAttack:
|
| | | useSkill = skill
|
| | | break
|
| | | atkOK = SkillShell.DoLogic_UseSkill(curNPC, tagObj, useSkill, tick)
|
| | | elif turnBattleType == ChConfig.TurnBattleType_Combo:
|
| | | if not tagObj:
|
| | | return
|
| | |
| | | xpMax = IpyGameDataPY.GetFuncCfg("AngerXP", 2)
|
| | | skillManager = curNPC.GetSkillManager()
|
| | | useSkillList = []
|
| | | GameWorld.DebugLog('skillCount=%s' % skillManager.GetSkillCount(), npcID)
|
| | | #GameWorld.DebugLog('skillCount=%s' % skillManager.GetSkillCount(), npcID)
|
| | | for index in range(0, skillManager.GetSkillCount()):
|
| | | useSkill = skillManager.GetSkillByIndex(index)
|
| | | #已经到尾部了
|
| | | if not useSkill or useSkill.GetSkillTypeID() == 0:
|
| | | break
|
| | | if useSkill.GetFuncType() in [ChConfig.Def_SkillFuncType_NormalAttack]:
|
| | | #基础普攻不能主动释放,目前仅用于反击
|
| | | continue
|
| | | #被动技能无法使用
|
| | | if SkillCommon.isPassiveSkill(useSkill):
|
| | | continue
|
| | |
| | | if atkOK:
|
| | | AddTurnFightXP(curNPC, __GetAddXP_Attack(curNPC, useSkill), "skillID:%s" % skillID)
|
| | | break
|
| | | |
| | | if not atkOK:
|
| | | tagObj = GetEnemyObj(curNPC)
|
| | | if tagObj:
|
| | | GameWorld.DebugLog(' 无技能可攻击,直接使用普攻! tagID=%s(%s)' % (tagObj.GetID(), GetObjName(tagObj)), npcID)
|
| | | atkOK = BaseAttack.Attack(curNPC, tagObj, None, tick)
|
| | |
|
| | | curNPC.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, 0) # 无论攻击成功与否都重置战斗类型
|
| | |
|
| | |
| | | posNum = atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo) % 100
|
| | | if posNum <= 0:
|
| | | GameWorld.DebugLog(" 被非主战单位攻击时无法触发反击: atkID=%s,posNum=%s" % (atkObj.GetID(), posNum))
|
| | | return False
|
| | | atkDistType = AttackCommon.GetAtkDistType(defObj)
|
| | | if atkDistType == ChConfig.AtkDistType_Long:
|
| | | if not IpyGameDataPY.GetFuncCfg("ParryCfg", 2):
|
| | | GameWorld.DebugLog(" 远程单位不可反击: defID=%s" % (defObj.GetID()))
|
| | | return False
|
| | | defAtkBackRate = GameObj.GetAtkBackRate(defObj) # 防方反击率
|
| | | atkBackNum = defObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnAtkBackNum) # 已反击次数
|
| | |
| | | for posNum, curNPC in batLineup.npcPosDict.items():
|
| | | objID = curNPC.GetID()
|
| | | npcID = curNPC.GetNPCID()
|
| | | heroID = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_HeroID)
|
| | | atkHurt = hurtStatDict.get(objID, 0)
|
| | | defHurt = defStatDict.get(objID, 0)
|
| | | cureHP = cureStatDict.get(objID, 0)
|
| | | GameWorld.DebugLog(" Pos:%s ID=%s-%s,,HP=%s/%s, 输出=%s,承伤=%s,治疗=%s" |
| | | % (posNum, objID, npcID, GameObj.GetHP(curNPC), GameObj.GetMaxHP(curNPC), atkHurt, defHurt, cureHP))
|
| | | lineupStatInfo[str(posNum)] = {"ObjID":objID, "NPCID":npcID, "AtkHurt":atkHurt, "DefHurt":defHurt, "CureHP":cureHP}
|
| | | GameWorld.DebugLog(" Pos:%s ID=%s-%s-%s,,HP=%s/%s, 输出=%s,承伤=%s,治疗=%s" |
| | | % (posNum, objID, npcID, heroID, GameObj.GetHP(curNPC), GameObj.GetMaxHP(curNPC), atkHurt, defHurt, cureHP))
|
| | | lineupStatInfo[str(posNum)] = {"ObjID":objID, "HeroID":heroID, "NPCID":npcID, "AtkHurt":atkHurt, "DefHurt":defHurt, "CureHP":cureHP}
|
| | |
|
| | | awardItemList = []
|
| | | playerID = turnFight.playerID
|
| | |
| | | #---Obj字典-------
|
| | | Def_Obj_Dict_Faction = 'Faction' # 所属阵营
|
| | | Def_Obj_Dict_LineupPlayerID = 'LineupPlayerID' # 阵容所属玩家ID,可用于判断是否玩家阵容,PVP或PVE
|
| | | Def_Obj_Dict_HeroID = 'HeroID' # 该战斗NPC所绑定的武将ID,一般仅玩家阵容有
|
| | | Def_Obj_Dict_SkinID = 'SkinID' # 该战斗NPC所绑定的武将皮肤ID,一般仅玩家阵容有
|
| | | Def_Obj_Dict_TurnFightPosInfo = 'TurnFightPosInfo' # 回合制站位: 阵营编号*100+阵型站位,阵型站位为0时代表非主战单位
|
| | | Def_Obj_Dict_TurnFightTimeline = 'TurnFightTimeline' # 回合制战斗时间线: 回合数*100+行动编号节点
|
| | | Def_Obj_Dict_TurnComboNum = 'TurnComboNum' # 单次累计连击次数
|
| | |
| | | Def_SkillFuncType_ShentongSkill, #20 神通技能
|
| | | Def_SkillFuncType_ElfSkill, #21 精怪技能
|
| | | Def_SkillFuncType_GatherTheSoul, #22 聚魂技能
|
| | | ) = range(23)
|
| | | Def_SkillFuncType_TurnNormaAttack, #23 回合普攻技能
|
| | | ) = range(24)
|
| | |
|
| | | # 受技能效果完全影响的怪, 对应 Def_BattleRelationType_CommNoBoss
|
| | | Def_SkillAttack_NPCIsBoss = [ Def_NPCType_Ogre_Normal , #平凡小怪 0 # c++ 定义为普通NPC视野刷新
|
| | |
| | | Def_BattleRelationType_CommNoBoss, # 除了(指定)BOSS,可对其释放技能,但是无实际效果
|
| | | ) = range(0, 4)
|
| | |
|
| | | # 近战远程
|
| | | AtkDistTypeList = (
|
| | | AtkDistType_Short, # 近战
|
| | | AtkDistType_Long, # 远程
|
| | | ) = range(1, 1 + 2)
|
| | |
|
| | | # 经验倍率限制类型
|
| | | (
|
| | | ExpRateLimitType_Recover, # 资源找回
|
| | |
| | | class tagSCTurnFightObj(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("ObjID", c_int), # 实例唯一ID
|
| | | ("NPCID", c_int), # 绑定的NPCID,不同的实例ID对应的NPCID可能一样
|
| | | ("ObjID", c_int), # 战斗单位唯一ID
|
| | | ("NPCID", c_int), # 战斗NPCID,不同的实例ID对应的NPCID可能一样
|
| | | ("HeroID", c_int), # 玩家武将ID,仅玩家阵容有
|
| | | ("SkinID", c_int), # 玩家武将皮肤ID,仅玩家阵容有
|
| | | ("HP", c_int), # 当前血量,求余20亿部分
|
| | | ("HPEx", c_int), # 当前血量,整除20亿部分
|
| | | ("MaxHP", c_int), # 最大血量,求余20亿部分
|
| | |
| | | def Clear(self):
|
| | | self.ObjID = 0
|
| | | self.NPCID = 0
|
| | | self.HeroID = 0
|
| | | self.SkinID = 0
|
| | | self.HP = 0
|
| | | self.HPEx = 0
|
| | | self.MaxHP = 0
|
| | |
| | | DumpString = '''// B4 24 回合战斗初始化 //tagSCTurnFightInit:
|
| | | ObjID:%d,
|
| | | NPCID:%d,
|
| | | HeroID:%d,
|
| | | SkinID:%d,
|
| | | HP:%d,
|
| | | HPEx:%d,
|
| | | MaxHP:%d,
|
| | |
| | | %(
|
| | | self.ObjID,
|
| | | self.NPCID,
|
| | | self.HeroID,
|
| | | self.SkinID,
|
| | | self.HP,
|
| | | self.HPEx,
|
| | | self.MaxHP,
|
| | |
| | | def IsFBPass(curPlayer, mapID, lineID):
|
| | | ## 副本线路是否已过关
|
| | | passLineID = 0
|
| | | if mapID == ChConfig.Def_FBMapID_Main:
|
| | | return PlayerControl.IsMainLevelPass(curPlayer, lineID)
|
| | | if mapID == ChConfig.Def_FBMapID_RealmTower:
|
| | | passLineID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_RealmTowerFloor)
|
| | | elif mapID == ChConfig.Def_FBMapID_SkyTower:
|
| | |
| | | ("DWORD", "HeroID", 1),
|
| | | ("BYTE", "Country", 0),
|
| | | ("BYTE", "Quality", 0),
|
| | | ("list", "SkinNPCIDList", 0),
|
| | | ("BYTE", "AtkDistType", 0),
|
| | | ("list", "SkinIDList", 0),
|
| | | ("DWORD", "NormalSkillID", 0),
|
| | | ("DWORD", "AngerSkillID", 0),
|
| | | ("WORD", "AtkInheritPer", 0),
|
| | |
| | | ),
|
| | |
|
| | | "HeroSkin":(
|
| | | ("DWORD", "SkinNPCID", 1),
|
| | | ("DWORD", "SkinID", 1),
|
| | | ("list", "WearAttrIDList", 0),
|
| | | ("list", "WearAttrValueList", 0),
|
| | | ("list", "AllBatAttrIDList", 0),
|
| | |
| | | ("DWORD", "NPCID", 1),
|
| | | ("BYTE", "FightPowerLackAtkLimit", 0),
|
| | | ("DWORD", "SuppressFightPower", 0),
|
| | | ("BYTE", "AtkDictType", 0),
|
| | | ("BYTE", "AtkDistType", 0),
|
| | | ("DWORD", "Atk", 0),
|
| | | ("DWORD", "Def", 0),
|
| | | ("DWORD", "MaxHP", 0),
|
| | |
| | | def GetHeroID(self): return self.attrTuple[0] # 英雄ID DWORD
|
| | | def GetCountry(self): return self.attrTuple[1] # 国家 BYTE
|
| | | def GetQuality(self): return self.attrTuple[2] # 品质 BYTE
|
| | | def GetSkinNPCIDList(self): return self.attrTuple[3] # 皮肤NPCID列表 list
|
| | | def GetNormalSkillID(self): return self.attrTuple[4] # 普攻技能ID DWORD
|
| | | def GetAngerSkillID(self): return self.attrTuple[5] # 怒气技能ID DWORD
|
| | | def GetAtkInheritPer(self): return self.attrTuple[6] # 攻击继承 WORD
|
| | | def GetDefInheritPer(self): return self.attrTuple[7] # 防御继承 WORD
|
| | | def GetHPInheritPer(self): return self.attrTuple[8] # 生命继承 WORD
|
| | | def GetBatAttrDict(self): return self.attrTuple[9] # 其他战斗属性字典 {"属性ID":值, ...} dict |
| | | def GetAtkDistType(self): return self.attrTuple[3] # 远近类型;1-近战;2-远程 BYTE
|
| | | def GetSkinIDList(self): return self.attrTuple[4] # 皮肤ID列表 list
|
| | | def GetNormalSkillID(self): return self.attrTuple[5] # 普攻技能ID DWORD
|
| | | def GetAngerSkillID(self): return self.attrTuple[6] # 怒气技能ID DWORD
|
| | | def GetAtkInheritPer(self): return self.attrTuple[7] # 攻击继承 WORD
|
| | | def GetDefInheritPer(self): return self.attrTuple[8] # 防御继承 WORD
|
| | | def GetHPInheritPer(self): return self.attrTuple[9] # 生命继承 WORD
|
| | | def GetBatAttrDict(self): return self.attrTuple[10] # 其他战斗属性字典 {"属性ID":值, ...} dict |
| | | |
| | | # 武将星级天赋表 |
| | | class IPY_HeroTalent(): |
| | |
| | | def GetAttrIDList(self): return self.attrTuple[2] # 属性ID列表 list
|
| | | def GetAttrValueList(self): return self.attrTuple[3] # 属性值列表 list |
| | | |
| | | # 武将皮肤表 |
| | | # 皮肤表 |
| | | class IPY_HeroSkin(): |
| | | |
| | | def __init__(self): |
| | | self.attrTuple = None |
| | | return |
| | | |
| | | def GetSkinNPCID(self): return self.attrTuple[0] # 皮肤NPCID DWORD
|
| | | def GetSkinID(self): return self.attrTuple[0] # 皮肤NPCID DWORD
|
| | | def GetWearAttrIDList(self): return self.attrTuple[1] # 穿戴属性ID列表 list
|
| | | def GetWearAttrValueList(self): return self.attrTuple[2] # 穿戴属性值列表 list
|
| | | def GetAllBatAttrIDList(self): return self.attrTuple[3] # 全体上阵属性ID列表 list
|
| | |
| | | def GetNPCID(self): return self.attrTuple[0] # NPCID DWORD
|
| | | def GetFightPowerLackAtkLimit(self): return self.attrTuple[1] # 战力不足限制攻击 BYTE
|
| | | def GetSuppressFightPower(self): return self.attrTuple[2] # 推荐/压制战力 DWORD
|
| | | def GetAtkDictType(self): return self.attrTuple[3] # 远近类型;1-近战;2-远程 BYTE
|
| | | def GetAtkDistType(self): return self.attrTuple[3] # 远近类型;1-近战;2-远程 BYTE
|
| | | def GetAtk(self): return self.attrTuple[4] # 攻击力 DWORD
|
| | | def GetDef(self): return self.attrTuple[5] # 防御值 DWORD
|
| | | def GetMaxHP(self): return self.attrTuple[6] # 最大生命值,可超过20E DWORD
|
| | |
| | | SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_ForbidenTalk, 0)
|
| | | return
|
| | |
|
| | | def IsMainLevelPass(curPlayer, lvID):
|
| | | ## 判断玩家是否过关某个主线关卡ID
|
| | | # @param lvID: 关卡唯一ID,与策划约定好 = 章节*100+关卡编号
|
| | | passChapterID, passLevelNum, _ = GetMainLevelPassInfo(curPlayer)
|
| | | passValue = passChapterID * 100 + passLevelNum # 因为pass的记录是带波数的,即当前关卡boss还没过关,所以只有大于该记录值的才算过关
|
| | | return passValue > lvID
|
| | |
|
| | | ## 主线关卡过关进度值 = 章节*10000+关卡编号*100+第x波
|
| | | def GetMainLevelPassValue(curPlayer): return curPlayer.GetExAttr1()
|
| | | def SetMainLevelPassValue(curPlayer, value): curPlayer.SetExAttr1(value, False, False) # 不通知GameServer
|
| | |
| | | heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
|
| | | if not heroIpyData:
|
| | | return
|
| | | skinNPCIDList = heroIpyData.GetSkinNPCIDList()
|
| | | skinIDList = heroIpyData.GetSkinIDList()
|
| | | if skinIndex > 0: # 0的为默认皮肤,不做限制
|
| | | if skinIndex >= len(skinNPCIDList):
|
| | | if skinIndex >= len(skinIDList):
|
| | | GameWorld.DebugLog("该武将不存在该皮肤! heroID=%s,skinIndex=%s" % (heroID, skinIndex))
|
| | | return
|
| | | skinState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroSkin % heroID)
|
| | |
| | | RealmTaskType_LV, # 等级 1
|
| | | RealmTaskType_PassMap, # 过关关卡 2
|
| | | RealmTaskType_UseXiantao, # 消耗战锤 3
|
| | | ) = range(1, 1 + 3)
|
| | | RealmTaskType_TreeLV, # 仙树等级 4
|
| | | ) = range(1, 1 + 4)
|
| | |
|
| | | # 需要记录任务值的任务类型列表
|
| | | NeedTaskValueTypeList = [RealmTaskType_UseXiantao]
|
| | |
| | | % (realmLV, taskID, taskType, mapID, lineID), playerID)
|
| | | return
|
| | |
|
| | | # 仙树等级
|
| | | elif taskType == RealmTaskType_TreeLV:
|
| | | treeLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLV)
|
| | | if treeLV < needValueA:
|
| | | GameWorld.DebugLog('境界任务领奖,仙树在祝福等级不足! realmLV=%s,taskID=%s,taskType=%s,treeLV=%s < %s' |
| | | % (realmLV, taskID, taskType, treeLV, needValueA), playerID)
|
| | | return
|
| | | |
| | | # 根据记录任务进度值
|
| | | elif taskType in NeedTaskValueTypeList:
|
| | | curValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_RealmTaskValue % taskID)
|
| | |
| | | import GameFuncComm
|
| | | import ShareDefine
|
| | | import ChConfig
|
| | | import FBCommon
|
| | |
|
| | | def GetTaskIDList(taskGroup):
|
| | | ## 获取某个任务分组所有任务ID列表
|
| | |
| | | if len(conds) != 2:
|
| | | return 0
|
| | | mapID, lineID = conds
|
| | | passLineID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FBPassLineID % mapID)
|
| | | taskValue = 1 if passLineID >= lineID else 0
|
| | | taskValue = 1 if FBCommon.IsFBPass(curPlayer, mapID, lineID) else 0
|
| | |
|
| | | elif taskType == ChConfig.TaskType_TreeLV:
|
| | | taskValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLV)
|
| | |
| | | ## 是否xp怒气技能
|
| | | return curSkill and curSkill.GetXP() > 0
|
| | |
|
| | | def isNormalAtkSkill(curSkill):
|
| | | ## 是否普攻技能,区别与无技能的普通A一下,该普攻同样可以有各种技能效果,只是他属于普攻
|
| | | return curSkill and curSkill.GetFuncType() == ChConfig.Def_SkillFuncType_NormalAttack
|
| | | def isTurnNormalAtkSkill(curSkill):
|
| | | ## 是否回合普攻技能,区别与无技能的普通A一下,该普攻同样可以有各种技能效果,只是他属于普攻
|
| | | return curSkill and curSkill.GetFuncType() == ChConfig.Def_SkillFuncType_TurnNormaAttack
|
| | |
|
| | | ## 检查技能是否为被动技能, 用于控制不可释放技能
|
| | | def isPassiveSkill(curSkill):
|