From efc4f490488935020d1b58a451a396ee420de9da Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期三, 06 八月 2025 18:21:05 +0800
Subject: [PATCH] 129 【战斗】战斗系统-服务端(NPC、技能使用新表N.NPC表卡牌、J.技能表卡牌;重构战斗系统;优化战利品掉落;)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py | 17
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py | 2
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py | 477 ++++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py | 3
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py | 1164 +++++---------
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py | 578 +++++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py | 152 -
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py | 231 +-
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BaseAttack.py | 14
PySysDB/PySysDBPY.h | 92
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py | 26
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NetPackCommon.py | 3
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py | 899 +++++++++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Hero.py | 6
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py | 29
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ObjPool.py | 498 ++++++
/dev/null | 236 --
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MainLevel.py | 6
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuff.py | 74
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py | 16
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldEvent.py | 4
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py | 51
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py | 8
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py | 10
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py | 86
25 files changed, 3,408 insertions(+), 1,274 deletions(-)
diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index dd16eba..b46fd5f 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -26,10 +26,71 @@
BYTE OPLimitInAct; //活动期间限制队伍操作
};
+//NPC表
+
+struct NPC
+{
+ DWORD _NPCID; //NPCID
+ char NPCName; //名称
+ BYTE Country; //国家
+ BYTE AtkDistType; //远近类型;1-近战;2-远程
+ WORD LV; //等级
+ DWORD Atk; //攻击力
+ DWORD Def; //防御值
+ DWORD MaxHP; //最大生命值,可超过20E
+ list SkillIDList; //技能ID列表
+ DWORD FinalDamPer; //最终增伤
+ DWORD FinalDamPerDef; //最终减伤
+ DWORD MissRate; //闪避概率
+ DWORD MissRateDef; //抗闪避概率
+ DWORD SuperHitRate; //暴击概率
+ DWORD SuperHitRateDef; //抗暴击概率
+ DWORD StunRate; //击晕概率
+ DWORD StunRateDef; //抗击晕概率
+ DWORD ComboRate; //连击概率
+ DWORD ComboRateDef; //抗连击概率
+ DWORD ParryRate; //格挡概率
+ DWORD ParryRateDef; //抗格挡概率
+ DWORD SuckHPPer; //吸血比率
+ DWORD SuckHPPerDef; //抗吸血比率
+ dict SpecAttrInfo; //特殊属性信息 {"属性ID":值, ...}
+};
+
+//技能表
+struct Skill
+{
+ DWORD _SkillID; //技能ID
+ DWORD SkillTypeID; //技能TypeID
+ WORD SkillMaxLV; //最高等级
+ char SkillName; //技能名
+ BYTE FuncType; //功能分类
+ BYTE SkillType; //技能类型
+ BYTE HurtType; //伤害类型
+ BYTE AtkType; //释放方式
+ BYTE TagAim; //瞄准位置
+ BYTE TagFriendly; //敌我目标
+ BYTE TagAffect; //目标细分
+ BYTE TagCount; //目标个数
+ WORD HappenRate; //释放或添加几率
+ WORD LastTime; //持续时间
+ WORD CoolDownTime; //冷却时间
+ WORD Priority; //优先级
+ DWORD EffectID1; //效果ID1
+ list EffectValues1; //效果值列表1
+ DWORD EffectID2; //效果ID2
+ list EffectValues2; //效果值列表2
+ DWORD EffectID3; //效果ID3
+ list EffectValues3; //效果值列表3
+ DWORD ConnSkill; //关联技能
+ list EnhanceSkillList; //触发技能ID列表
+ DWORD FightPower; //技能战斗力
+};
+
//武将表
struct Hero
{
DWORD _HeroID; //英雄ID
+ char Name; //名称
BYTE Country; // 国家
BYTE Quality; // 品质
BYTE AtkDistType; //远近类型;1-近战;2-远程
@@ -157,7 +218,6 @@
{
BYTE _ChapterID; //章节ID
list DailyBootyUpperList; // 每日战利品掉落上限,[[物品ID,每日上限], ...]
- list BootyWeightList; // 战利品掉落权重,[[权重,物品ID,掉落个数下限, 上限], ...]
};
//主线关卡表
@@ -917,36 +977,6 @@
float AttrPer; //对应等级表中的比例
dict AttrSpecDict; //特殊属性值字典 {attrKey:value, ...}
dict AttrExDict; //特殊属性值字典 {attrKey:value, ...}
-};
-
-//NPC表扩展
-
-struct tagNPCEx
-{
- DWORD _NPCID; //NPCID
- BYTE FightPowerLackAtkLimit; //战力不足限制攻击
- DWORD SuppressFightPower; //推荐/压制战力
- BYTE AtkDistType; //远近类型;1-近战;2-远程
- DWORD Atk; //攻击力
- DWORD Def; //防御值
- DWORD MaxHP; //最大生命值,可超过20E
- list SkillIDList; //技能ID列表
- DWORD FinalHurtPer; //最终增伤
- DWORD FinalHurtReducePer; //最终减伤
- DWORD MissRate; //闪避概率
- DWORD MissDefRate; //抗闪避概率
- DWORD SuperHitRate; //暴击概率
- DWORD SuperHitRateReduce; //抗暴击概率
- DWORD FaintRate; //击晕概率
- DWORD FaintDefRate; //抗击晕概率
- DWORD ComboRate; //连击概率
- DWORD ComboDefRate; //抗连击概率
- DWORD ParryRate; //格挡概率
- DWORD ParryDefRate; //抗格挡概率
- DWORD ParryDamPer; //格挡减伤比率
- DWORD SuckHPPer; //吸血比率
- DWORD SuckHPDefPer; //抗吸血比率
- dict SpecAttrInfo; //特殊属性信息 {"属性ID":值, ...}
};
//成长型境界怪物表
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
index 4f4bdcb..c1f70d4 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
@@ -454,7 +454,7 @@
return heroIpyData.GetAtkDistType()
npcID = curObj.GetNPCID()
- npcDataEx = NPCCommon.GetNPCDataEx(npcID)
+ npcDataEx = NPCCommon.GetNPCDataPy(npcID)
if npcDataEx:
return npcDataEx.GetAtkDistType()
@@ -872,14 +872,14 @@
PlayerControl.NotifyCode(atkPlayer, sysMark)
return False
- npcDataEx = NPCCommon.GetNPCDataEx(npcID)
- if npcDataEx and npcDataEx.GetFightPowerLackAtkLimit():
- if npcDataEx.GetSuppressFightPower() > PlayerControl.GetFightPower(atkPlayer):
- if isNotify:
- PlayerControl.NotifyCode(atkPlayer, "BossFightPowerHint")
- #GameWorld.DebugLog("战力不足,无法攻击boss! npcID=%s,SuppressFightPower=%s > playerFightPower=%s"
- # % (npcID, npcDataEx.GetSuppressFightPower(), PlayerControl.GetFightPower(atkPlayer)))
- return False
+ #npcDataEx = NPCCommon.GetNPCDataPy(npcID)
+ #if npcDataEx and npcDataEx.GetFightPowerLackAtkLimit():
+ # if npcDataEx.GetSuppressFightPower() > PlayerControl.GetFightPower(atkPlayer):
+ # if isNotify:
+ # PlayerControl.NotifyCode(atkPlayer, "BossFightPowerHint")
+ # #GameWorld.DebugLog("战力不足,无法攻击boss! npcID=%s,SuppressFightPower=%s > playerFightPower=%s"
+ # # % (npcID, npcDataEx.GetSuppressFightPower(), PlayerControl.GetFightPower(atkPlayer)))
+ # return False
return True
@@ -2150,9 +2150,6 @@
aBurnValue = atkwargs.get('burnValue', 0)
aBurnPer = atkwargs.get('burnPer', 0)
hurtFormulaKey = atkwargs.get('hurtFormulaKey', None)
- #if hurtFormulaKey == "Burn":
- # pass
- #else:
hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("DOTFormula", 1))
elif not curSkill:
hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("HurtFormula", 3))
@@ -2240,7 +2237,7 @@
else:
defObj.SetDict(ChConfig.Def_PlayerKey_LastAttackerObjID, atkObj.GetID())
- TurnAttack.AddTurnObjHurtValue(atkObj, defObj, resultHurtType.HurtType, resultHurtType.RealHurtHP, resultHurtType.LostHP, curSkill)
+ #TurnAttack.AddTurnObjHurtValue(atkObj, defObj, resultHurtType.HurtType, resultHurtType.RealHurtHP, resultHurtType.LostHP, curSkill)
#if resultHurtType.RealHurtHP:
# PassiveBuffEffMng.OnPassiveSkillTrigger(defObj, atkObj, None, ChConfig.TriggerType_BeHurt, tick)
@@ -2708,8 +2705,8 @@
if GameObj.GetHP(curObjDetel) > 0:
return
- if TurnAttack.SetTurnObjKilled(curObjDetel, atkObj):
- return
+ #if TurnAttack.SetTurnObjKilled(curObjDetel, atkObj):
+ # return
#---玩家处理---
if curObjDetel.GetGameObjType() == IPY_GameWorld.gotPlayer:
@@ -2787,7 +2784,7 @@
srcID, srcType = 0, 0
if srcObj:
srcID, srcType = srcObj.GetID(), srcObj.GetGameObjType()
- turnFight = TurnAttack.GetTurnFightMgr().getNPCTurnFight(curObj.GetID())
+ turnFight = TurnAttack.GetTurnFightMgr().getTurnFight(curObj.GetTFGUID())
if turnFight:
clientPack = ChNetSendPack.tagObjPropertyRefreshView()
clientPack.ObjID = curObj.GetID()
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_NormalNPC.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_NormalNPC.py
deleted file mode 100644
index 08f7962..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_NormalNPC.py
+++ /dev/null
@@ -1,119 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package NormalNPC_Attack_NormalNPC.py
-# 普通NPC攻击普通NPC
-#
-# @author adaws
-# @date 2010-11-17 19:00
-# @version 1.3
-#
-# @change: "2010-11-18 13:50" chenxuewei Npc杀死NPC时通知副本
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2016-09-28 21:00" hxp 不死boss逻辑支持
-#------------------------------------------------------------------------------
-#"""Version = 2016-09-28 21:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import AttackCommon
-import ChConfig
-import FBLogic
-import SkillShell
-import ChNPC
-import GameObj
-import GameWorld
-import TurnAttack
-#---------------------------------------------------------------------
-Def_FB_NPCAI_SideList = []
-#---------------------------------------------------------------------
-
-## 是否可以攻击
-# @param attacker 攻击方:普通NPC
-# @param curTagPlayer 防守方:召唤兽
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True or False
-# @remarks 函数详细说明.
-def GetCanAttack(attacker, defender, skill, tick):
- return AttackCommon.CheckNPCCanAttackTag(attacker, defender, skill)
-
-
-## 获得关系
-# @param attacker 攻击方:普通NPC
-# @param defender 防守方:普通NPC
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-# @remarks 函数详细说明.
-def GetTagRelation(attacker, defender, skill, tick):
- # 优先级高于其他
- atkLimit = ChNPC.GetNPCAttackTagLimit(attacker, defender)
- if atkLimit:
- return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None
-
- attackerCampType = GameObj.GetFaction(attacker)
- defenderCampType = GameObj.GetFaction(defender)
-
- #不同阵营是敌人
- if attackerCampType != defenderCampType:
- return ChConfig.Type_Relation_Enemy, ChConfig.Def_PASysMessage_None
-
- #机器人可以打机器人
- if attacker.GetType() == ChConfig.ntRobot and defender.GetType() == ChConfig.ntRobot:
- return ChConfig.Type_Relation_Enemy, ChConfig.Def_PASysMessage_None
-
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-
-
-## 攻击
-# @param attacker 攻击方:普通NPC
-# @param curTagPlayer 防守方:普通NPC
-# @param skill 技能(无->None)
-# @param skillValue 技能增强
-# @param skillPercent 技能增强百分比
-# @param skillHurtList 技能伤血列表(C++接口)
-# @param tick 当前时间
-# @return hurtType : HurtType 伤害结构体类
-# @remarks 函数详细说明.
-def DoAttack(attacker, defender, skill, skillValue, skillPercent, skillHurtList, tick):
- #计算反弹,添加伤血
- hurtType = AttackCommon.GetHurtHP(attacker, defender, skill, skillValue, skillPercent, tick)
- hurtHP = hurtType.HurtHP
- FBLogic.DoFB_NPC_HurtNPC(attacker, defender, hurtHP)
-
- npcControl = NPCCommon.NPCControl(defender)
- npcControl.AddObjDetelToAngryList_ByAttack(attacker, hurtHP, skill)
-
- #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
- AttackCommon.AddHurt(defender, skillHurtList, hurtType.HurtType, hurtHP)
- #ChNPC.OnUndeathBossHurt(defender, hurtHP)
- return hurtType
-
-## 处理攻击后的结果
-# @param attacker 攻击方:普通NPC
-# @param curTagPlayer 防守方:普通NPC
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True
-# @remarks 函数详细说明.
-def AttackResult(attacker, defender, skill, tick):
-
- if ChNPC.OnUndeathBossAttacked(defender):
- return
-
- #普通NPC
- if GameObj.GetHP(defender) <= 0:
- if TurnAttack.SetTurnObjKilled(defender, attacker):
- return
- if not ChNPC.OnCheckCanDie(attacker, defender, skill, tick):
- return
- #副本
- FBLogic.DoFB_Npc_KillNPC(attacker, defender, tick)
-
- npcControl = NPCCommon.NPCControl(defender)
- npcControl.SetKilled()
-
- return True
-
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Pet.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Pet.py
deleted file mode 100644
index e52fc10..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Pet.py
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package NormalNPC_Attack_Pet
-# @todo: 普通NPC攻击宠物
-#
-# @author chenxuewei
-# @date 2010-06-26
-# @version 1.3
-#
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-11-17 19:00" adaws 加入NPC阵容判定
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-#------------------------------------------------------------------------------
-"""Version = 2012-02-10 20:20"""
-#---------------------------------------------------------------------
-import PlayerControl
-import AttackCommon
-import ChConfig
-import ChEquip
-import BaseAttack
-import PetControl
-import NPCCommon
-import SkillShell
-import GameObj
-#---------------------------------------------------------------------
-
-## 是否可以攻击
-# @param curNormalNPC 攻击方:普通NPC
-# @param curTagPet 防守方:玩家宠物
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True or False
-# @remarks 是否可以攻击
-def GetCanAttack(curNormalNPC, curTagPet, skill, tick):
- return False
- #===========================================================================
- # if not AttackCommon.CheckNPCCanAttackTag(curNormalNPC, curTagPet, skill):
- # return False
- #
- # return True
- #===========================================================================
-
-#---------------------------------------------------------------------
-## 获得关系
-# @param curNormalNPC 攻击方:普通NPC
-# @param curTagPet 防守方:玩家宠物
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-# @remarks 函数详细说明.
-def GetTagRelation(curNormalNPC, curTagPet, skill, tick):
- return ChConfig.Type_Relation_None , ChConfig.Def_PASysMessage_None
- defenderCampType = NPCCommon.GetFaction(curNormalNPC)
- #正义的 不攻击玩家 宠物以及玩家的召唤兽
- if defenderCampType == ChConfig.CampType_Justice:
- return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None
-
- return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
-#---------------------------------------------------------------------
-## 攻击
-# @param curNormalNPC 攻击方:普通NPC
-# @param curTagPet 防守方:玩家宠物
-# @param skill 技能(无->None)
-# @param skillValue 技能增强
-# @param skillPercent 技能增强百分比
-# @param skillHurtList 技能伤血列表(C++接口)
-# @param tick 当前时间
-# @return hurtType : HurtType 伤害结构体类
-# @remarks 攻击
-def DoAttack(curNormalNPC, curTagPet, skill, skillValue, skillPercent, skillHurtList, tick):
- #计算反弹,添加伤血
- curNPCBeHP = GameObj.GetHP(curNormalNPC)
- hurtType = AttackCommon.GetHurtHP(curNormalNPC, curTagPet, skill, skillValue, skillPercent, tick)
- hurtHP = hurtType.HurtHP
-
- #添加仇恨
- petControl = NPCCommon.NPCControl(curTagPet)
- petControl.AddObjDetelToAngryList_ByAttack(curNormalNPC, hurtHP, skill)
-
- #判断NPC是否伤血,如果伤血,说明反弹伤害,要加伤血列表
- lastHP = curNPCBeHP - GameObj.GetHP(curNormalNPC)
-
- curTagPlayer = PetControl.GetPetOwner(curTagPet) # 宠物主人
-
- if curTagPlayer != None:
- if lastHP > 0:
- #添加伤血列表
- AttackCommon.NPCAddObjInHurtList(curTagPlayer, curNormalNPC, curNPCBeHP, lastHP)
-
- #给这个玩家的其他召唤兽增加仇恨(打主人优先->这里只添加1点仇恨)
- AttackCommon.SummonAddAngryByOwner(curNormalNPC, curTagPlayer, 1)
-
- #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
- AttackCommon.AddHurt(curTagPet, skillHurtList, hurtType.HurtType, hurtHP)
- return hurtType
-#---------------------------------------------------------------------
-## 处理攻击后的结果
-# @param curNormalNPC 攻击方:普通NPC
-# @param curTagPet 防守方:玩家宠物
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True
-# @remarks 处理攻击后的结果
-def AttackResult(curNormalNPC, curTagPet, skill, tick):
- curTagPlayer = PetControl.GetPetOwner(curTagPet) # 宠物主人
-
- if curTagPlayer != None and GameObj.GetHP(curTagPlayer) > 0:
- #进入战斗状态
- AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
-
- #宠物死亡
- if GameObj.GetHP(curTagPet) <= 0:
- curTagPetNPCControl = NPCCommon.NPCControl(curTagPet)
- curTagPetNPCControl.SetKilled()
-
- return True
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Player.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Player.py
deleted file mode 100644
index 678d07c..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Player.py
+++ /dev/null
@@ -1,119 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package NormalNPC_Attack_Player
-# 普通NPC攻击玩家
-#
-# @author eggxp
-# @date 2010-4-20
-# @version 1.4
-# @change: "2013-03-25 10:00" wdb 去装备使用不扣耐久
-# @change: "2013-06-25 11:00" Alee 修改系统提示
-# @change: "2013-09-27 19:30" Alee 恢复耐久
-# @change: "2016-07-04 17:00" hxp 玩家被NPC击杀提示信息前置(防止先处理死亡逻辑后有些地方可能会清怪,导致NPCID找不到)
-#------------------------------------------------------------------------------------------------------------
-#"""Version = 2016-07-04 17:00"""
-#---------------------------------------------------------------------
-import PlayerControl
-import AttackCommon
-import ChConfig
-import FBLogic
-import GameObj
-import NPCCommon
-import ChNPC
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击
-# @param curNormalNPC 攻击方:普通NPC
-# @param curTagPlayer 防守方:玩家
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True or False
-# @remarks 函数详细说明.
-def GetCanAttack(curNormalNPC, curTagPlayer, skill, tick):
- if not AttackCommon.CheckNPCCanAttackTag(curNormalNPC, curTagPlayer, skill):
- return False
-
- return True
-
-## 获得关系
-# @param curNormalNPC 攻击方:普通NPC
-# @param curTagPlayer 防守方:玩家
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-# @remarks 函数详细说明.
-def GetTagRelation(curNormalNPC, curTagPlayer, skill, tick):
- # 优先级高于其他
- atkLimit = ChNPC.GetNPCAttackTagLimit(curNormalNPC, curTagPlayer)
- if atkLimit:
- return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None
-
- defenderCampType = NPCCommon.GetFaction(curNormalNPC)
- tagFaction = curTagPlayer.GetFaction()
- if tagFaction and defenderCampType:
- if tagFaction == defenderCampType:
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
- return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
- #正义的 不攻击玩家 宠物以及玩家的召唤兽
- elif defenderCampType == ChConfig.CampType_Justice:
- return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None
-
- return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
-## 攻击
-# @param curNormalNPC 攻击方:普通NPC
-# @param curTagPlayer 防守方:玩家
-# @param skill 技能(无->None)
-# @param skillValue 技能增强
-# @param skillPercent 技能增强百分比
-# @param skillHurtList 技能伤血列表(C++接口)
-# @param tick 当前时间
-# @return hurtType : HurtType 伤害结构体类
-# @remarks 函数详细说明.
-def DoAttack(curNormalNPC, curTagPlayer, skill, skillValue, skillPercent, skillHurtList, tick):
- #计算反弹,添加伤血
- curNPCBeHP = GameObj.GetHP(curNormalNPC)
- hurtType = AttackCommon.GetHurtHP(curNormalNPC, curTagPlayer, skill, skillValue, skillPercent, tick)
- hurtHP = hurtType.HurtHP
- #判断NPC是否伤血,如果伤血,说明反弹伤害,要加伤血列表
- lastHP = curNPCBeHP - GameObj.GetHP(curNormalNPC)
- if lastHP > 0 :
- #添加伤血列表
- AttackCommon.NPCAddObjInHurtList(curTagPlayer, curNormalNPC, curNPCBeHP, lastHP, True)
- #给这个玩家的召唤兽增加仇恨
- AttackCommon.SummonAddAngryByOwner(curNormalNPC, curTagPlayer, hurtHP)
- #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
- AttackCommon.AddHurt(curTagPlayer, skillHurtList, hurtType.HurtType, hurtHP)
- return hurtType
-
-## 处理攻击后的结果
-# @param curNormalNPC 攻击方:普通NPC
-# @param curTagPlayer 防守方:玩家
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True
-# @remarks 函数详细说明.
-def AttackResult(curNormalNPC, curTagPlayer, skill, tick):
-
- #玩家活着
- if GameObj.GetHP(curTagPlayer) > 0:
- #被攻击玩家进入战斗状态
- AttackCommon.OnNPCHitPlayer(curNormalNPC, curTagPlayer, tick)
- AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
- else:
- #通知玩家
- if curTagPlayer.GetMapID() != ChConfig.Def_FBMapID_XMZZ:
- if curNormalNPC.GetType() == ChConfig.ntRobot:
- PlayerControl.NotifyCode(curTagPlayer, 'RobotKill_1', [curNormalNPC.GetID(), curNormalNPC.GetNPCID()])
- else:
- PlayerControl.NotifyCode(curTagPlayer, 'GeRen_chenxin_279029', [curNormalNPC.GetNPCID()])
- #玩家已经死亡
- playerControl = PlayerControl.PlayerControl(curTagPlayer)
- playerControl.SetDead()
- FBLogic.DoFBOnNPCKill_Player(curNormalNPC, curTagPlayer, tick)
- return True
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_SummonNPC.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_SummonNPC.py
deleted file mode 100644
index 194814d..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_SummonNPC.py
+++ /dev/null
@@ -1,146 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package NormalNPC_Attack_SummonNPC
-# 普通NPC攻击召唤NPC
-#
-# @author eggxp
-# @date 2010-4-20
-# @version 1.5
-#
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-11-17 19:00" adaws 加入NPC阵容判定
-# @change: "2010-11-18 11:00" adaws NPC阵容判定错修改
-# @change: "2011-05-05 17:30" Alee 攻击关系判断
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-#------------------------------------------------------------------------------
-"""Version = 2012-02-10 20:20"""
-#---------------------------------------------------------------------
-import NPCCommon
-import AttackCommon
-import ChConfig
-import IPY_GameWorld
-import GameWorld
-import SkillShell
-import TurnAttack
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击
-# @param curNormalNPC 攻击方:普通NPC
-# @param curTagPlayer 防守方:召唤兽
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True or False
-# @remarks 函数详细说明.
-def GetCanAttack(curNormalNPC, curTagSummon, skill, tick):
- if not AttackCommon.CheckNPCCanAttackTag(curNormalNPC, curTagSummon, skill):
- return False
-
- return True
-
-## 获得关系
-# @param curNormalNPC 攻击方:普通NPC
-# @param curTagPlayer 防守方:召唤兽
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-# @remarks 函数详细说明.
-def GetTagRelation(curNormalNPC, curTagSummon, skill, tick):
- #1.不攻击精灵
- if curTagSummon.GetType() == IPY_GameWorld.ntFairy:
- return ChConfig.Type_Relation_None , ChConfig.Def_PASysMessage_None
-
- #判断阵营
- attackerCampType = GameObj.GetFaction(curNormalNPC)
- defenderCampType = GameObj.GetFaction(curTagSummon)
-
- if attackerCampType != defenderCampType:
- return ChConfig.Type_Relation_Enemy, ChConfig.Def_PASysMessage_None
-
- #2.不攻击阵营相同(不包括二者都为中立)
- if not (attackerCampType == ChConfig.CampType_Neutral and defenderCampType == ChConfig.CampType_Neutral):
- if attackerCampType == defenderCampType:
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-
- #召唤兽的主人
- curSummonOwner = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummon)
- if curSummonOwner == None:
- curSummonOwner = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotNPC, curTagSummon)
-
- if curSummonOwner != None:
- if GameWorld.IsSameObj(curSummonOwner, curNormalNPC) :
- #3.不攻击自己的召唤兽
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-
- #4.不攻击NPC召唤兽
- if curSummonOwner.GetGameObjType() == IPY_GameWorld.gotNPC:
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-
- return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
-## 攻击
-# @param curNormalNPC 攻击方:普通NPC
-# @param curTagPlayer 防守方:召唤兽
-# @param skill 技能(无->None)
-# @param skillValue 技能增强
-# @param skillPercent 技能增强百分比
-# @param skillHurtList 技能伤血列表(C++接口)
-# @param tick 当前时间
-# @return hurtType : HurtType 伤害结构体类
-# @remarks 函数详细说明.
-def DoAttack(curNormalNPC, curTagSummonNPC, skill, skillValue, skillPercent, skillHurtList, tick):
- #计算反弹,添加伤血
- curNPCBeHP = GameObj.GetHP(curNormalNPC)
- hurtType = AttackCommon.GetHurtHP(curNormalNPC, curTagSummonNPC, skill, skillValue, skillPercent, tick)
- hurtHP = hurtType.HurtHP
-
- #添加仇恨
- summonControl = NPCCommon.NPCControl(curTagSummonNPC)
- summonControl.AddObjDetelToAngryList_ByAttack(curNormalNPC, hurtHP, skill)
-
- #判断NPC是否伤血,如果伤血,说明反弹伤害,要加伤血列表
- lastHP = curNPCBeHP - GameObj.GetHP(curNormalNPC)
-
- curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummonNPC)
-
- if curTagPlayer != None :
- if lastHP > 0 :
- #添加伤血列表
- AttackCommon.NPCAddObjInHurtList(curTagPlayer, curNormalNPC, curNPCBeHP, lastHP)
-
- #给这个玩家的其他召唤兽增加仇恨(打主人优先->这里只添加1点仇恨)
- AttackCommon.SummonAddAngryByOwner(curNormalNPC, curTagPlayer, 1)
-
- #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
- AttackCommon.AddHurt(curTagSummonNPC, skillHurtList, hurtType.HurtType, hurtHP)
- return hurtType
-
-## 处理攻击后的结果
-# @param curNormalNPC 攻击方:普通NPC
-# @param curTagPlayer 防守方:召唤兽
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True
-# @remarks 函数详细说明.
-def AttackResult(curNormalNPC, curTagSummonNPC, skill, tick):
- #获取召唤兽的主人
- curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummonNPC)
- if curTagPlayer != None and GameObj.GetHP(curTagPlayer) > 0 :
- #进入战斗状态
- AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
-
- #召唤兽死亡
- if GameObj.GetHP(curTagSummonNPC) <= 0:
- if TurnAttack.SetTurnObjKilled(curTagSummonNPC, curNormalNPC):
- return
- curTagSummonNPCControl = NPCCommon.NPCControl(curTagSummonNPC)
- #召唤兽死亡
- curTagSummonNPCControl.SetKilled()
-
- return True
-
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_NormalNPC.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_NormalNPC.py
deleted file mode 100644
index f47b37a..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_NormalNPC.py
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package Pet_Attack_NormalNPC
-# 宠物攻击普通NPC
-#
-# @author chenxuewei
-# @date 2010-06-26
-# @version 1.7
-#
-# @change: "2010-07-01 17:20" chenxuewei 修复bug:宠物攻击NPC的仇恨值只加在宠物身上,不添加在其主人身上。
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-09-13 14:51" panwei 宠物攻击也给玩家添加一份仇恨
-# @change: "2010-11-17 19:00" adaws 加入NPC阵容判定
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2013-11-08 18:00" hxp 增加NPC被攻击逻辑入口
-# @change: "2016-09-28 21:00" hxp 不死boss逻辑支持
-#------------------------------------------------------------------------------
-#"""Version = 2016-09-28 21:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import AttackCommon
-import SkillCommon
-import ChConfig
-import FBLogic
-import PetControl
-import SkillShell
-import ChNPC
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击
-# @param curPet 攻击方:宠物
-# @param curTagNormalNPC 防守方:普通NPC
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True or False
-# @remarks 是否可以攻击
-def GetCanAttack(curPet, curTagNormalNPC, skill, tick):
-
- if not AttackCommon.CheckNPCCanAttackTag(curPet, curTagNormalNPC, skill):
- return False
-
- return True
-
-
-## 获得关系
-# @param curPet 攻击方:宠物
-# @param curTagNormalNPC 防守方:普通NPC
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-# @remarks 获得关系
-def GetTagRelation(curPet, curTagNormalNPC, skill, tick):
- defenderCampType = NPCCommon.GetFaction(curTagNormalNPC)
- #不攻击正义的需要去保护的 这里有女神和守卫
- if defenderCampType == ChConfig.CampType_Justice:
- return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None
-
- return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
-
-## 攻击
-# @param curPet 攻击方:宠物
-# @param curTagPlayer 防守方:普通NPC
-# @param skill 技能(无->None)
-# @param skillValue 技能增强
-# @param skillPercent 技能增强百分比
-# @param skillHurtList 技能伤血列表(C++接口)
-# @param tick 当前时间
-# @return hurtType : HurtType 伤害结构体类
-# @remarks 攻击
-def DoAttack(curPet, curTagNPC, skill, skillValue, skillPercent, skillHurtList, tick):
- curTagNPCHPBeforeAtk = GameObj.GetHP(curTagNPC)
- hurtType = AttackCommon.GetHurtHP(curPet, curTagNPC, skill, skillValue, skillPercent, tick)
- hurtHP = hurtType.HurtHP
-
- npcControl = NPCCommon.NPCControl(curTagNPC)
- curPetOwner = PetControl.GetPetOwner(curPet) # 宠物主人
-
- #无法查找主人,添加自己
- if curPetOwner:
- AttackCommon.NPCAddObjInHurtList(curPetOwner, curTagNPC, curTagNPCHPBeforeAtk, hurtHP)
- npcControl.AddObjDetelToAngryList_ByAttack(curPetOwner, hurtHP, skill)
-
- #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
- AttackCommon.AddHurt(curTagNPC, skillHurtList, hurtType.HurtType, hurtHP)
- #ChNPC.OnUndeathBossHurt(curTagNPC, hurtHP)
- return hurtType
-
-
-## 处理攻击后的结果
-# @param curPet 攻击方:宠物
-# @param curTagPlayer 防守方:普通NPC
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True
-# @remarks 处理攻击后的结果
-def AttackResult(curPet, curTagNPC, skill, tick):
-
- if ChNPC.OnUndeathBossAttacked(curTagNPC):
- return
-
- #NPC死亡
- if GameObj.GetHP(curTagNPC) <= 0:
- #执行击杀NPC逻辑
- curPlayer = PetControl.GetPetOwner(curPet) # 宠物主人
-
- if not ChNPC.OnCheckCanDie(curPlayer, curTagNPC, skill, tick):
- return
-
- if curPlayer != None:
- NPCCommon.OnPlayerAttackNPCDie(curTagNPC, curPlayer, skill)
- FBLogic.DoFB_Player_KillNPC(curPlayer, curTagNPC, tick)
-
- curTagNormalNPCControl = NPCCommon.NPCControl(curTagNPC)
- curTagNormalNPCControl.SetKilled()
- else:
- ChNPC.OnNPCAttacked(curPet, curTagNPC, skill, tick)
-
-
- return True
-
-
\ No newline at end of file
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_Pet.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_Pet.py
deleted file mode 100644
index d02b0c4..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_Pet.py
+++ /dev/null
@@ -1,135 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package Pet_Attack_Pet
-# 宠物攻击宠物
-#
-# @author chenxuewei
-# @date 2010-06-26
-# @version 1.5
-#
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-09-27 17:55" panwei 取消GM不可攻击限制
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2012-06-25 13:00" jiang 攻击宠物玩家红名
-# @change: "2016-02-26 17:00" hxp 增加PVP伤害统计
-#------------------------------------------------------------------------------
-#"""Version = 2016-02-26 17:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import AttackCommon
-import SkillCommon
-import ChConfig
-import GameWorld
-import PetControl
-import SkillShell
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击
-# @param curPet 攻击方:宠物
-# @param curTagPet 防守方:宠物
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True or False
-# @remarks 是否可以攻击
-def GetCanAttack(curPet, curTagPet, skill, tick):
- return False
- #return AttackCommon.CheckNPCCanAttackTag(curPet, curTagPet, skill)
-
-## 获得关系
-# @param curPet 攻击方:宠物
-# @param curTagPet 防守方:宠物
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-# @remarks 获得关系
-def GetTagRelation(curPet, curTagPet, skill, tick):
-
- return ChConfig.Type_Relation_None , ChConfig.Def_PASysMessage_None
-
- curPlayer = PetControl.GetPetOwner(curPet) # 宠物主人
-
- curTagPlayer = PetControl.GetPetOwner(curTagPet) # 宠物主人
-
- if curPlayer != None and curTagPlayer != None:
- #同一玩家不互相攻击
- if GameWorld.IsSameObj(curPlayer, curTagPlayer):
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-
- #检查攻击模式
- if not AttackCommon.CheckPlayerAttackMode_Player(curPlayer, curTagPlayer):
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_AttackMode
-
- #------------------------以下逻辑,都是玩家可以攻击目标的情况下
-
- return AttackCommon.GetPlayersRelation(curPlayer, curTagPlayer)
-
- #不同类型的,可以直接攻击
- return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
-## 攻击
-# @param curPet 攻击方:宠物
-# @param curTagPet 防守方:宠物
-# @param skill 技能(无->None)
-# @param skillValue 技能增强
-# @param skillPercent 技能增强百分比
-# @param skillHurtList 技能伤血列表(C++接口)
-# @param tick 当前时间
-# @return hurtType : HurtType 伤害结构体类
-# @remarks 攻击
-def DoAttack(curPet, curTagPet, skill, skillValue, skillPercent, skillHurtList, tick):
- hurtType = AttackCommon.GetHurtHP(curPet, curTagPet, skill, skillValue, skillPercent, tick)
- hurtHP = hurtType.HurtHP
- #添加仇恨
- curTagPetControl = NPCCommon.NPCControl(curTagPet)
- curTagPetControl.AddObjDetelToAngryList_ByAttack(curPet, hurtHP, skill)
-
- #---攻击方为召唤兽,给主人加仇恨---
- curPetOwner = PetControl.GetPetOwner(curPet) # 宠物主人
-
- if curPetOwner != None:
- curTagPetControl.AddObjToAngryList(curPetOwner, 1)
-
- curTagPlayer = PetControl.GetPetOwner(curTagPet) # 宠物主人
- if curTagPlayer != None:
- AttackCommon.OnPVPDamage(curPetOwner, hurtHP, curTagPlayer, "Pet v Pet")
-
- #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
- AttackCommon.AddHurt(curTagPet, skillHurtList, hurtType.HurtType, hurtHP)
-
- return hurtType
-
-## 处理攻击后的结果
-# @param curPet 攻击方:宠物
-# @param curTagPet 防守方:宠物
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True
-# @remarks 处理攻击后的结果
-def AttackResult(curPet, curTagPet, skill, tick):
-
- curTagPlayer = PetControl.GetPetOwner(curTagPet) # 宠物主人
- curPlayer = PetControl.GetPetOwner(curPet) # 宠物主人
-
- if curTagPlayer != None and GameObj.GetHP(curTagPlayer) > 0:
- #进入战斗状态
- AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
-
- #是否在特殊的副本中
- if curPlayer != None:
- AttackCommon.OnPlayerHitPlayer(curPlayer, curTagPlayer, tick)
-
- #宠物死亡
- if GameObj.GetHP(curTagPet) <= 0:
- curTagPetNPCControl = NPCCommon.NPCControl(curTagPet)
- curTagPetNPCControl.SetKilled()
-
- if curPlayer != None and curTagPlayer != None:
- AttackCommon.AddPKValue(curPlayer, curTagPlayer, tick)
-
- return True
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_Player.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_Player.py
deleted file mode 100644
index ae825f3..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_Player.py
+++ /dev/null
@@ -1,162 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package Pet_Attack_Player
-# @todo: 宠物攻击玩家
-#
-# @author chenxuewei
-# @date 2010-06-26
-# @version 2.0
-#
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-09-27 17:55" panwei 取消GM不可攻击限制
-# @change: "2011-02-12 17:30" Alee 注释攻击类型相关
-# @change: "2011-10-26 14:20" chengaobao 增加逻辑:乘骑状态被攻击,自动下马
-# @change: "2011-10-27 17:20" chengaobao 将乘骑状态被攻击,自动下马逻辑移到BaseAttack中
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2012-10-19 14:30" jiang 添加具体的伤害,用于副本计算
-# @change: "2013-11-05 21:00" Alee PK提示
-# @change: "2015-06-03 14:00" hxp 处理击杀逻辑后再SetDead,防止清除临时黄名后PK惩罚关系判断错误
-# @change: "2016-02-26 17:00" hxp 增加PVP伤害统计
-#------------------------------------------------------------------------------
-#"""Version = 2016-02-26 17:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import PlayerControl
-import AttackCommon
-import SkillCommon
-import ChConfig
-import GameWorld
-import ChEquip
-import PetControl
-import SkillShell
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击
-# @param curPet 攻击方:宠物
-# @param curTagPlayer 防守方:玩家
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True or False
-# @remarks 是否可以攻击
-def GetCanAttack(curPet, curTagPlayer, skill, tick):
- return AttackCommon.CheckNPCCanAttackTag(curPet, curTagPlayer, skill)
-
-## 获得关系
-# @param curPet 攻击方:宠物
-# @param curTagPlayer 防守方:玩家
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-# @remarks 获得关系
-def GetTagRelation(curPet, curTagPlayer, skill, tick):
-
- curPetOwner = PetControl.GetPetOwner(curPet) # 宠物主人
- if curPetOwner == None:
- return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
- #宠物不能攻击自己的主人
- if GameWorld.IsSameObj(curPetOwner, curTagPlayer):
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-
- #判断主人的攻击模式,判断是否可以攻击这个玩家
- if not AttackCommon.CheckPlayerAttackMode_Player(curPetOwner, curTagPlayer):
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_AttackMode
-
- #------------------------以下逻辑,都是玩家可以攻击目标的情况下
-
- return AttackCommon.GetPlayersRelation(curPetOwner, curTagPlayer)
-
-
-## 攻击
-# @param curPet 攻击方:宠物
-# @param curTagPlayer 防守方:玩家
-# @param skill 技能(无->None)
-# @param skillValue 技能增强
-# @param skillPercent 技能增强百分比
-# @param skillHurtList 技能伤血列表(C++接口)
-# @param tick 当前时间
-# @return hurtType : HurtType 伤害结构体类
-# @remarks 攻击
-def DoAttack(curPet, curTagPlayer, skill, skillValue, skillPercent, skillHurtList, tick):
- curTagPlayerHPBeforeAtk = GameObj.GetHP(curTagPlayer)
- hurtType = AttackCommon.GetHurtHP(curPet, curTagPlayer, skill, skillValue, skillPercent, tick)
- #伤血
- hurtHP = hurtType.HurtHP
-
- curAttackPlayer = PetControl.GetPetOwner(curPet) # 宠物主人
-
- #2个玩家的召唤兽互相PK,需要判断防守方玩家的是否可以攻击进攻方
- if curAttackPlayer != None:
- #if AttackCommon.CheckPlayerAttackMode_Player(curTagPlayer, curAttackPlayer):
- # AttackCommon.SummonAddAngryByOwner(curPet, curTagPlayer, hurtHP)
-
- #AttackCommon.NPCAddObjInHurtList(curAttackPlayer, curTagPlayer, curTagPlayerHPBeforeAtk, hurtHP)
-
- AttackCommon.OnPVPDamage(curAttackPlayer, hurtHP, curTagPlayer, "Pet v Player")
-
- #直接攻击
- #else:
- # AttackCommon.SummonAddAngryByOwner(curPet, curTagPlayer, hurtHP)
-
- #添加伤血列表
-
- #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
- AttackCommon.AddHurt(curTagPlayer, skillHurtList, hurtType.HurtType, hurtHP)
- return hurtType
-
-
-## 处理攻击后的结果
-# @param curPet 攻击方:宠物
-# @param curTagPlayer 防守方:玩家
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True
-# @remarks 处理攻击后的结果
-def AttackResult(curPet, curTagPlayer, skill, tick):
-
- #防守方血量
- curTagPlayerHP = GameObj.GetHP(curTagPlayer)
-
- #是否同国籍
- #获得攻击方拥有者
- curPlayer = PetControl.GetPetOwner(curPet) # 宠物主人
-
- #被攻击提示,避免频繁提示
- #===========================================================================
- # if not curTagPlayer.GetBattleState():
- # PlayerControl.NotifyCode(curTagPlayer, "PK_admin_0")
- #
- # if curPlayer != None and not curPlayer.GetBattleState():
- # PlayerControl.NotifyCode(curTagPlayer, "PK_admin_0")
- #===========================================================================
-
- #玩家是否死亡
- if curTagPlayerHP > 0:
- #被攻击者也进入战斗状态
- AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
-
- #是否在特殊的副本中
- if curPlayer != None:
- AttackCommon.OnPlayerHitPlayer(curPlayer, curTagPlayer, tick)
-
- return
-
- if curPlayer != None:
- #执行玩家击杀玩家逻辑
- AttackCommon.OnPlayerKillPlayer(curPlayer, curTagPlayer, tick)
-
- #刷新NPC的仇恨列表,删除死亡对象
- #npcControl = NPCCommon.NPCControl(curPet)
- #npcControl.RefreshAngryList(tick)
-
- #玩家已经死亡
- tagPlayerControl = PlayerControl.PlayerControl(curTagPlayer)
- tagPlayerControl.SetDead()
-
- return True
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_SummonNPC.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_SummonNPC.py
deleted file mode 100644
index 86bcd47..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_SummonNPC.py
+++ /dev/null
@@ -1,140 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package Pet_Attack_SummonNPC
-# @todo: 宠物攻击召唤兽
-#
-# @author chenxuewei
-# @date 2010-06-26
-# @version 1.4
-#
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-09-27 17:55" panwei 取消GM不可攻击限制
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2016-02-26 17:00" hxp 增加PVP伤害统计
-#------------------------------------------------------------------------------
-#"""Version = 2016-02-26 17:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import AttackCommon
-import SkillCommon
-import ChConfig
-import IPY_GameWorld
-import GameWorld
-import PetControl
-import SkillShell
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击
-# @param curPet 攻击方:宠物
-# @param curTagSummon 防守方:召唤兽
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True or False
-# @remarks 是否可以攻击
-def GetCanAttack(curPet, curTagSummon, skill, tick):
- return AttackCommon.CheckNPCCanAttackTag(curPet, curTagSummon, skill)
-
-## 获得关系
-# @param curPet 攻击方:宠物
-# @param curTagSummon 防守方:召唤兽
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-# @remarks 获得关系
-def GetTagRelation(curPet, curTagSummon, skill, tick):
-
- curPlayer = PetControl.GetPetOwner(curPet) # 宠物主人
-
- if curPlayer == None:
- return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
- curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummon)
-
- if curTagPlayer == None:
- return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
- if curPlayer != None and curTagPlayer != None:
- #同一玩家不互相攻击
- if GameWorld.IsSameObj(curPlayer, curTagPlayer):
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-
- #检查攻击模式
- if not AttackCommon.CheckPlayerAttackMode_Player(curPlayer, curTagPlayer):
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_AttackMode
-
- #------------------------以下逻辑,都是玩家可以攻击目标的情况下
-
- return AttackCommon.GetPlayersRelation(curPlayer, curTagPlayer)
-
- #不同类型的,可以直接攻击
- return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
-
-## 攻击
-# @param curPet 攻击方:宠物
-# @param curTagSummon 防守方:召唤兽
-# @param skill 技能(无->None)
-# @param skillValue 技能增强
-# @param skillPercent 技能增强百分比
-# @param skillHurtList 技能伤血列表(C++接口)
-# @param tick 当前时间
-# @return hurtType : HurtType 伤害结构体类
-# @remarks 攻击
-def DoAttack(curPet, curTagSummon, skill, skillValue, skillPercent, skillHurtList, tick):
- hurtType = AttackCommon.GetHurtHP(curPet, curTagSummon, skill, skillValue, skillPercent, tick)
-
- hurtHP = hurtType.HurtHP
- #添加仇恨
- summonControl = NPCCommon.NPCControl(curTagSummon)
- #summonControl.AddObjDetelToAngryList_ByAttack(curPet, hurtHP, skill)
-
- #---攻击方为召唤兽,给主人加仇恨---
- curPetOwner = PetControl.GetPetOwner(curPet) # 宠物主人
-
- if curPetOwner != None:
- summonControl.AddObjToAngryList(curPetOwner, 1)
-
- curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummon)
- if curTagPlayer != None:
- AttackCommon.OnPVPDamage(curPetOwner, hurtHP, curTagPlayer, "Pet v Summon")
-
- #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
- AttackCommon.AddHurt(curTagSummon, skillHurtList, hurtType.HurtType, hurtHP)
- return hurtType
-
-
-## 处理攻击后的结果
-# @param curPet 攻击方:宠物
-# @param curTagSummon 防守方:召唤兽
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True
-# @remarks 处理攻击后的结果
-def AttackResult(curPet, curTagSummon, skill, tick):
-
- #获取防守方召唤兽的主人
- curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummon)
- #攻击的是玩家的召唤兽
- if curTagPlayer != None and GameObj.GetHP(curTagPlayer) > 0:
- #进入战斗状态
- AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
- #获取召唤兽的主人
- curPlayer = PetControl.GetPetOwner(curPet) # 宠物主人
-
- #是否在特殊的副本中
- if curPlayer != None:
- AttackCommon.OnPlayerHitPlayer(curPlayer, curTagPlayer, tick)
-
- #防守方召唤兽死亡
- if GameObj.GetHP(curTagSummon) <= 0:
- curTagSummonNPCControl = NPCCommon.NPCControl(curTagSummon)
- #召唤兽死亡
- curTagSummonNPCControl.SetKilled()
-
- return True
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_NormalNPC.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_NormalNPC.py
deleted file mode 100644
index 0a5446e..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_NormalNPC.py
+++ /dev/null
@@ -1,141 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package Player_Attack_NormalNPC
-# 玩家攻击普通NPC
-#
-# @author eggxp
-# @date 2010-4-20
-# @version 1.8
-#
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-11-17 19:00" adaws 加入NPC阵容判定
-# @change: "2011-07-15 18:00" zhangd 添加NPC被玩家打死后触发逻辑
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2013-11-08 18:00" hxp 增加NPC被攻击逻辑入口
-# @change: "2015-03-05 21:30" hxp 伤血类型检查触发被动技能
-# @change: "2015-04-11 15:30" hxp 增加最终伤害逻辑
-# @change: "2016-09-28 21:00" hxp 不死boss逻辑支持
-#------------------------------------------------------------------------------
-#"""Version = 2016-09-28 21:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import ChConfig
-import AttackCommon
-import GameWorld
-import FBLogic
-import ChEquip
-import IPY_GameWorld
-import SkillCommon
-import SkillShell
-import ChNPC
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击
-# @param curNormalNPC 攻击方:玩家
-# @param curTagPlayer 防守方:普通NPC
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True or False
-# @remarks 函数详细说明.
-def GetCanAttack(curPlayer, curTagNormalNPC, skill, tick):
- #通用判断
- if not AttackCommon.CheckPlayerCanAttackTag(curPlayer, curTagNormalNPC):
- return False
-
- if not AttackCommon.CheckPlayerAttackDist(curPlayer, curTagNormalNPC, skill):
- return False
-
- return True
-
-## 获得关系
-# @param curNormalNPC 攻击方:玩家
-# @param curTagPlayer 防守方:普通NPC
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-# @remarks 函数详细说明.
-def GetTagRelation(curPlayer, curTagNormalNPC, skill, tick):
- defenderCampType = NPCCommon.GetFaction(curTagNormalNPC)
- curFaction = curPlayer.GetFaction()
- if curFaction and defenderCampType:
- if curFaction == defenderCampType:
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
- return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
- #不攻击正义的需要去保护的 这里有女神和守卫
- elif defenderCampType == ChConfig.CampType_Justice:
- return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None
-
- #私有木桩只能自己打自己的
- if curTagNormalNPC.GetType() in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:
- summonPlayerID = curTagNormalNPC.GetDictByKey(ChConfig.Def_NPC_Dict_PriWoodPilePlayerID)
- if curPlayer.GetPlayerID() != summonPlayerID:
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
- return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
- return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
-## 攻击
-# @param curNormalNPC 攻击方:玩家
-# @param curTagPlayer 防守方:普通NPC
-# @param skill 技能(无->None)
-# @param skillValue 技能增强
-# @param skillPercent 技能增强百分比
-# @param skillHurtList 技能伤血列表(C++接口)
-# @param tick 当前时间
-# @return hurtType : HurtType 伤害结构体类
-# @remarks 函数详细说明.
-def DoAttack(curPlayer, curTagNormalNPC, skill, skillValue, skillPercent, skillHurtList, tick):
-
- curTagNPCHPBeforeAtk = GameObj.GetHP(curTagNormalNPC)
- hurtType = AttackCommon.GetHurtHP(curPlayer, curTagNormalNPC, skill, skillValue, skillPercent, tick)
-
- #伤血量
- hurtHP = hurtType.HurtHP
- #给这个普通小怪增加仇恨
- npcControl = NPCCommon.NPCControl(curTagNormalNPC)
- npcControl.AddObjDetelToAngryList_ByAttack(curPlayer, hurtHP, skill)
-
- #添加伤血列表
- AttackCommon.NPCAddObjInHurtList(curPlayer, curTagNormalNPC, curTagNPCHPBeforeAtk, hurtHP)
- #给这个玩家的所有召唤兽增加仇恨
- AttackCommon.SummonAddAngryByOwner(curTagNormalNPC, curPlayer, hurtHP)
- #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
- AttackCommon.AddHurt(curTagNormalNPC, skillHurtList, hurtType.HurtType, hurtHP)
-
- return hurtType
-
-## 处理攻击后的结果
-# @param curNormalNPC 攻击方:玩家
-# @param curTagPlayer 防守方:普通NPC
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True
-# @remarks 函数详细说明.
-def AttackResult(curPlayer, curTagNormalNPC, skill, tick):
- if ChNPC.OnUndeathBossAttacked(curTagNormalNPC):
- return
-
- if GameObj.GetHP(curTagNormalNPC) <= 0:
- if not ChNPC.OnCheckCanDie(curPlayer, curTagNormalNPC, skill, tick):
- return
- #执行击杀NPC逻辑
- NPCCommon.OnPlayerAttackNPCDie(curTagNormalNPC, curPlayer, skill)
- FBLogic.DoFB_Player_KillNPC(curPlayer , curTagNormalNPC , tick)
- #NPC死亡
- curTagNormalNPCControl = NPCCommon.NPCControl(curTagNormalNPC)
- curTagNormalNPCControl.SetKilled()
- else:
- ChNPC.OnNPCAttacked(curPlayer, curTagNormalNPC, skill, tick)
-
-
- return True
-
-
-
-
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_Pet.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_Pet.py
deleted file mode 100644
index 13d8df5..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_Pet.py
+++ /dev/null
@@ -1,146 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package Player_Attack_Pet
-# 玩家攻击宠物
-#
-# @author chenxuewei
-# @date 2010-06-26
-# @version 1.6
-#
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-09-27 17:55" panwei 取消GM不可攻击限制
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2012-06-13 18:00" jiang 攻击宠物玩家红名
-# @change: "2015-04-11 15:30" hxp 增加最终伤害逻辑
-# @change: "2016-02-26 17:00" hxp 增加PVP伤害统计
-#------------------------------------------------------------------------------
-"""Version = 2016-02-26 17:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import GameWorld
-import AttackCommon
-import IPY_GameWorld
-import PlayerControl
-import ChConfig
-import ChEquip
-import SkillCommon
-import PetControl
-import SkillShell
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击
-# @param curPlayer 攻击方:玩家
-# @param curTagPet 防守方:宠物
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True or False
-# @remarks 是否可以攻击
-def GetCanAttack(curPlayer, curTagPet, skill, tick):
- return False
- #===========================================================================
- # #通用判断
- # if not AttackCommon.CheckPlayerCanAttackTag(curPlayer, curTagPet):
- # return False
- #
- # #判断距离
- # if not AttackCommon.CheckPlayerAttackDist(curPlayer, curTagPet, skill):
- # return False
- #
- # return True
- #===========================================================================
-
-## 获得关系
-# @param curPlayer 攻击方:玩家
-# @param curTagPet 防守方:宠物
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-# @remarks 获得关系
-def GetTagRelation(curPlayer, curTagPet, skill, tick):
- return ChConfig.Type_Relation_None , ChConfig.Def_PASysMessage_None
- curTagPlayer = PetControl.GetPetOwner(curTagPet) # 宠物主人
-
- if curTagPlayer == None:
- return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
- #自己的宠物,不能攻击
- if GameWorld.IsSameObj(curPlayer, curTagPlayer):
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-
- #别人的宠物,判定玩家的攻击模式
- if not AttackCommon.CheckPlayerAttackMode_Player(curPlayer, curTagPlayer):
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_AttackMode
-
- #------------------------以下逻辑,都是玩家可以攻击目标的情况下
-
- return AttackCommon.GetPlayersRelation(curPlayer, curTagPlayer)
-
-
-## 攻击
-# @param curPlayer 攻击方:玩家
-# @param curTagPet 防守方:宠物
-# @param skill 技能(无->None)
-# @param skillValue 技能增强
-# @param skillPercent 技能增强百分比
-# @param skillHurtList 技能伤血列表(C++接口)
-# @param tick 当前时间
-# @return hurtType : HurtType 伤害结构体类
-# @remarks 攻击
-def DoAttack(curPlayer, curTagPet, skill, skillValue, skillPercent, skillHurtList, tick):
-
- #攻击前血量
- curTagPetHP = GameObj.GetHP(curTagPet)
- #攻击成功
- hurtType = AttackCommon.GetHurtHP(curPlayer, curTagPet, skill, skillValue, skillPercent, tick)
- hurtHP = hurtType.HurtHP
- #给召唤兽添加仇恨
- petControl = NPCCommon.NPCControl(curTagPet)
- petControl.AddObjDetelToAngryList_ByAttack(curPlayer, hurtHP, skill)
-
- #添加伤血列表
- AttackCommon.NPCAddObjInHurtList(curPlayer, curTagPet, curTagPetHP, hurtHP)
-
- curTagPlayer = PetControl.GetPetOwner(curTagPet) # 宠物主人
- if curTagPlayer != None:
- AttackCommon.OnPVPDamage(curPlayer, hurtHP, curTagPlayer, "Player v Pet")
-
- #给自己的其他召唤兽添加仇恨
- AttackCommon.SummonAddAngryByOwner(curTagPet, curPlayer, hurtHP)
- #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
- AttackCommon.AddHurt(curTagPet, skillHurtList, hurtType.HurtType, hurtHP)
- return hurtType
-
-
-## 处理攻击后的结果
-# @param curPlayer 攻击方:玩家
-# @param curTagPet 防守方:宠物
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True
-# @remarks 处理攻击后的结果
-def AttackResult(curPlayer, curTagPet, skill, tick):
-
- curTagPlayer = PetControl.GetPetOwner(curTagPet) # 宠物主人
-
- if curTagPlayer != None:
-
- if GameObj.GetHP(curTagPlayer) > 0:
- #进入战斗状态
- AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
-
- AttackCommon.OnPlayerHitPlayer(curPlayer, curTagPlayer, tick)
-
- #宠物死亡
- if GameObj.GetHP(curTagPet) <= 0:
- curTagPetNPCControl = NPCCommon.NPCControl(curTagPet)
- curTagPetNPCControl.SetKilled()
-
- if curPlayer != None and curTagPlayer != None:
- AttackCommon.AddPKValue(curPlayer, curTagPlayer, tick)
- return True
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_Player.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_Player.py
deleted file mode 100644
index eb1e2ee..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_Player.py
+++ /dev/null
@@ -1,144 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package Player_Attack_Player
-# 玩家攻击玩家
-#
-# @author eggxp
-# @date 2010-4-20
-# @version 1.7
-#
-# 修改时间 修改人 修改内容
-# @change: "2013-03-25 10:00" wdb 去装备使用不扣耐久
-# @change: "2013-09-27 19:30" Alee 恢复耐久
-# @change: "2013-11-05 21:00" Alee PK提示
-# @change: "2014-09-25 11:30" hxp 增加最终伤害衰减控制
-# @change: "2015-03-07 07:30" hxp 最终伤害影响控制, 伤血类型检查触发被动技能; 淬毒
-# @change: "2015-04-11 15:30" hxp 增加最终伤害逻辑
-# @change: "2016-02-26 17:00" hxp 增加PVP伤害统计
-#------------------------------------------------------------------------------
-"""Version = 2016-02-26 17:00"""
-#---------------------------------------------------------------------
-import PlayerControl
-import GameWorld
-import AttackCommon
-import ChConfig
-import BaseAttack
-import ChEquip
-import IPY_GameWorld
-import SkillShell
-import SkillCommon
-import PassiveBuffEffMng
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-
-## 是否可以攻击
-# @param curNormalNPC 攻击方:玩家
-# @param curTagPlayer 防守方:玩家
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True or False
-# @remarks 是否可以攻击
-def GetCanAttack(curPlayer, curTagPlayer, skill, tick):
- #通用判断
- if not AttackCommon.CheckPlayerCanAttackTag(curPlayer, curTagPlayer):
- return False
-
- #判断距离
- if not AttackCommon.CheckPlayerAttackDist(curPlayer, curTagPlayer, skill):
- return False
-
- return True
-
-## 获得关系
-# @param curNormalNPC 攻击方:玩家
-# @param curTagPlayer 防守方:玩家C
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-# @remarks 获得关系
-def GetTagRelation(curPlayer, curTagPlayer, skill, tick):
- #最高优先级, 选定的目标是自己, 返回朋友
- if GameWorld.IsSameObj(curPlayer, curTagPlayer) :
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-
- #攻击模式, 如果不可攻击, 返回朋友
- if not AttackCommon.CheckPlayerAttackMode_Player(curPlayer, curTagPlayer):
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_AttackMode
-
- #------------------------以下逻辑,都是玩家可以攻击目标的情况下
-
- return AttackCommon.GetPlayersRelation(curPlayer, curTagPlayer)
-
-
-## 攻击
-# @param curNormalNPC 攻击方:玩家
-# @param curTagPlayer 防守方:玩家
-# @param skill 技能(无->None)
-# @param skillValue 技能增强
-# @param skillPercent 技能增强百分比
-# @param skillHurtList 技能伤血列表(C++接口)
-# @param tick 当前时间
-# @return hurtType : HurtType 伤害结构体类
-# @remarks 攻击
-def DoAttack(curPlayer, curTagPlayer, skill, skillValue, skillPercent, skillHurtList, tick):
-
- curTagPlayerHPBeforeAtk = GameObj.GetHP(curTagPlayer)
-
- #玩家攻击玩家
- hurtType = AttackCommon.GetHurtHP(curPlayer, curTagPlayer, skill, skillValue, skillPercent, tick)
- hurtHP = hurtType.HurtHP
-
- #给双方的玩家召唤兽添加仇恨
- #攻击者添加
- AttackCommon.SummonAddAngryByOwner(curTagPlayer, curPlayer, hurtHP)
- #防御者添加
- AttackCommon.SummonAddAngryByOwner(curPlayer, curTagPlayer, hurtHP)
-
- #添加伤血列表
- #AttackCommon.NPCAddObjInHurtList(curPlayer, curTagPlayer, curTagPlayerHPBeforeAtk, hurtHP)
- AttackCommon.OnPVPDamage(curPlayer, hurtHP, curTagPlayer, "Player v Player")
-
- #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
- AttackCommon.AddHurt(curTagPlayer, skillHurtList, hurtType.HurtType, hurtHP)
-
- return hurtType
-
-
-## 处理攻击后的结果
-# @param curNormalNPC 攻击方:玩家
-# @param curTagPlayer 防守方:玩家
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True
-# @remarks 处理攻击后的结果
-def AttackResult(curPlayer, curTagPlayer, skill, tick):
- #防守方玩家血量
- curTagPlayerHP = GameObj.GetHP(curTagPlayer)
-
- #被攻击提示,避免频繁提示
- if not curTagPlayer.GetBattleState() or not curPlayer.GetBattleState():
- PlayerControl.NotifyCode(curTagPlayer, "PK_admin_0")
-
- #玩家活着
- if curTagPlayerHP > 0:
- #被攻击的玩家也进入战斗状态
- AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
- AttackCommon.OnPlayerHitPlayer(curPlayer, curTagPlayer, tick)
-
- else:
- AttackCommon.OnPlayerKillPlayer(curPlayer, curTagPlayer, tick)
-
- #玩家已经死亡
- tagPlayerControl = PlayerControl.PlayerControl(curTagPlayer)
- tagPlayerControl.SetDead()
-
- if skill != None:
- SkillCommon.CheckAddPoisonAtkBuff(skill.GetSkillTypeID(), curPlayer, curTagPlayer, tick)
-
- return True
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_SummonNPC.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_SummonNPC.py
deleted file mode 100644
index 4c6d6a8..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_SummonNPC.py
+++ /dev/null
@@ -1,155 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package Player_Attack_SummonNPC
-# 玩家攻击召唤NPC
-#
-# @author eggxp
-# @date 2010-4-20
-# @version 1.9
-#
-# 修改时间 修改人 修改内容
-# @change: "2010-05-12 18:30" zhengyang 添加注释
-# @change: "2010-05-28 15:50" chenxuewei 应策划刘鸿生需求:增加剑圣项目的PK规则
-# @change: "2010-06-02 10:50" chenxuewei 玩家可以攻击目标的情况下,获得玩家间的关系统一在AttackCommon处理
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-09-27 17:55" panwei 取消GM不可攻击限制
-# @change: "2011-07-15 18:00" zhangd 添加NPC被玩家打死后触发逻辑
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2015-04-11 15:30" hxp 增加最终伤害逻辑
-# @change: "2016-02-26 17:00" hxp 增加PVP伤害统计
-#------------------------------------------------------------------------------
-#"""Version = 2016-02-26 17:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import GameWorld
-import AttackCommon
-import IPY_GameWorld
-import ChConfig
-import FBLogic
-import GameObj
-import ChNPC
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击
-# @param curNormalNPC 攻击方:玩家
-# @param curTagPlayer 防守方:召唤兽
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True or False
-# @remarks 是否可以攻击
-def GetCanAttack(curPlayer, curTagSummonNPC, skill, tick):
- #通用判断
- if not AttackCommon.CheckPlayerCanAttackTag(curPlayer, curTagSummonNPC):
- return False
-
- #判断距离
- if not AttackCommon.CheckPlayerAttackDist(curPlayer, curTagSummonNPC, skill):
- return False
-
- return True
-
-## 获得关系
-# @param curNormalNPC 攻击方:玩家
-# @param curTagPlayer 防守方:召唤兽
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-# @remarks 获得关系
-def GetTagRelation(curPlayer, curTagSummonNPC, skill, tick):
- #获取召唤兽的主人
- curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummonNPC)
-
- if curTagPlayer == None :
- #怪物的召唤兽,不考虑攻击模式问题
- return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
- #私有木桩只能自己打自己的
- if curTagSummonNPC.GetType() in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:
- summonPlayerID = curTagSummonNPC.GetDictByKey(ChConfig.Def_NPC_Dict_PriWoodPilePlayerID)
- if curPlayer.GetPlayerID() != summonPlayerID:
- 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
-
- #别人的召唤兽,判定玩家的攻击模式
- if not AttackCommon.CheckPlayerAttackMode_Player(curPlayer, curTagPlayer):
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_AttackMode
-
- #------------------------以下逻辑,都是玩家可以攻击目标的情况下
-
- return AttackCommon.GetPlayersRelation(curPlayer, curTagPlayer)
-
-
-## 攻击
-# @param curNormalNPC 攻击方:玩家
-# @param curTagPlayer 防守方:召唤兽
-# @param skill 技能(无->None)
-# @param skillValue 技能增强
-# @param skillPercent 技能增强百分比
-# @param skillHurtList 技能伤血列表(C++接口)
-# @param tick 当前时间
-# @return hurtType : HurtType 伤害结构体类
-# @remarks 攻击
-def DoAttack(curPlayer, curTagSummon, skill, skillValue, skillPercent, skillHurtList, tick):
-
- #攻击前血量
- curTagSummonBeHP = GameObj.GetHP(curTagSummon)
- #攻击成功
- hurtType = AttackCommon.GetHurtHP(curPlayer, curTagSummon, skill, skillValue, skillPercent, tick)
- hurtHP = hurtType.HurtHP
- #给召唤兽添加仇恨
- summonControl = NPCCommon.NPCControl(curTagSummon)
- summonControl.AddObjDetelToAngryList_ByAttack(curPlayer, hurtHP, skill)
-
- #添加伤血列表
- AttackCommon.NPCAddObjInHurtList(curPlayer, curTagSummon, curTagSummonBeHP, hurtHP)
-
- curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummon)
- if curTagPlayer != None:
- AttackCommon.OnPVPDamage(curPlayer, hurtHP, curTagPlayer, "Player v Summon")
-
- #给自己的其他召唤兽添加仇恨
- AttackCommon.SummonAddAngryByOwner(curTagSummon, curPlayer, hurtHP)
- #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
- AttackCommon.AddHurt(curTagSummon, skillHurtList, hurtType.HurtType, hurtHP)
- return hurtType
-
-
-## 处理攻击后的结果
-# @param curNormalNPC 攻击方:玩家
-# @param curTagPlayer 防守方:召唤兽
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True
-# @remarks 处理攻击后的结果
-def AttackResult(curPlayer, curTagSummon, skill, tick):
- #获取召唤兽的主人
- curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummon)
- #如果是玩家的召唤兽逻辑处理(NPC的召唤兽不考虑)
- if curTagPlayer != None :
-
- if GameObj.GetHP(curTagPlayer) > 0:
- #进入战斗状态
- AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
-
- AttackCommon.OnPlayerHitPlayer(curPlayer, curTagPlayer, tick)
-
- #召唤兽死亡
- if GameObj.GetHP(curTagSummon) <= 0:
- NPCCommon.OnPlayerAttackNPCDie(curTagSummon, curPlayer, skill)
- FBLogic.DoFB_Player_KillNPC(curPlayer , curTagSummon , tick)
- #获得控制器
- curTagNormalNPCControl = NPCCommon.NPCControl(curTagSummon)
- curTagNormalNPCControl.SetKilled()
- else:
- ChNPC.OnNPCAttacked(curPlayer, curTagSummon, skill, tick)
-
- return True
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_NormalNPC.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_NormalNPC.py
deleted file mode 100644
index e964c30..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_NormalNPC.py
+++ /dev/null
@@ -1,165 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package SummonNPC_Attack_NormalNPC
-# @todo: 召唤兽攻击普通NPC
-#
-# @author: panwei
-# @date 2010-09-06
-# @version 2.1
-#
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-11-18 11:00" adaws NPC阵容判定错修改
-# @change: "2010-11-18 13:50" chenxuewei Npc杀死NPC时通知副本
-# @change: "2011-04-15 14:00" chenxuewei 修复bug9922:守护囚车,范围技能(玩家召回隐形NPC放群攻技能)可攻击己方囚车、守卫
-# @change: "2011-05-11 13:45" Alee 召唤兽是陷阱则把仇恨给主人
-# @change: "2011-05-12 14:00" Alee 陷阱改为灵仇恨全转移给主人
-# @change: "2011-05-12 17:00" chenxuewei AttackResult召唤兽有没主人都只要通知副本一次即可,避免重复通知
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2013-01-03 17:00" wdb 去除npc攻击造成的伤血记录
-# @change: "2013-11-08 18:00" hxp 增加NPC被攻击逻辑入口
-# @change: "2016-09-28 21:00" hxp 不死boss逻辑支持
-#------------------------------------------------------------------------------
-#"""Version = 2016-09-28 21:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import IPY_GameWorld
-import AttackCommon
-import ChConfig
-import GameWorld
-import FBLogic
-import SkillShell
-import ChNPC
-import GameObj
-import TurnAttack
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-## 是否可以攻击
-# @param curNormalNPC 攻击方:召唤兽
-# @param curTagPlayer 防守方:普通NPC
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return 布尔值
-# @remarks 函数详细说明.
-def GetCanAttack(curSummonNPC, curTagNormalNPC, skill, tick):
-
- return AttackCommon.CheckNPCCanAttackTag(curSummonNPC, curTagNormalNPC, skill)
-
-#---------------------------------------------------------------------
-## 获得关系
-# @param curNormalNPC 攻击方:召唤兽
-# @param curTagPlayer 防守方:普通NPC
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return 关系列表 如:[ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None]
-# @remarks 获得关系列表
-def GetTagRelation(curSummonNPC, curTagNormalNPC, skill, tick):
-
- #防守方阵营
- defenderCampType = GameObj.GetFaction(curTagNormalNPC)
-
- #玩家的召唤兽才能攻击普通NPC
- npcOwner_Player = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC)
-
- if npcOwner_Player != None:
-
- #不攻击正义的需要去保护的 这里有女神和守卫
- if defenderCampType == ChConfig.CampType_Justice:
- return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None
-
- return ChConfig.Type_Relation_Enemy, ChConfig.Def_PASysMessage_None
-
- #攻击方阵营
- attackerCampType = GameObj.GetFaction(curSummonNPC)
- if attackerCampType != defenderCampType:
- return ChConfig.Type_Relation_Enemy, ChConfig.Def_PASysMessage_None
- return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None
-#---------------------------------------------------------------------
-## 攻击
-# @param curNormalNPC 攻击方:召唤兽
-# @param curTagPlayer 防守方:普通NPC
-# @param skill 技能(无->None)
-# @param skillValue 技能增强
-# @param skillPercent 技能增强百分比
-# @param skillHurtList 技能伤血列表(C++接口)
-# @param tick 当前时间
-# @return hurtType : HurtType 伤害结构体类
-# @remarks 攻击逻辑
-def DoAttack(curSummonNPC, curTagNPC, skill, skillValue, skillPercent, skillHurtList, tick):
- curTagNPCHPBeforeAtk = GameObj.GetHP(curTagNPC)
- hurtType = AttackCommon.GetHurtHP(curSummonNPC, curTagNPC, skill,
- skillValue, skillPercent, tick)
- hurtHP = hurtType.HurtHP
- #---被攻击的NPC添加仇恨---
- curTagNPCControl = NPCCommon.NPCControl(curTagNPC)
- curTagNPCControl.AddObjDetelToAngryList_ByAttack(curSummonNPC, hurtHP, skill)
-
- #---被攻击的NPC添加伤血---
-
- #攻击方为召唤兽,添加到主人伤血中
- summonOwner = NPCCommon.GetSummonOwnerDetel(curSummonNPC)
-
- #2013-1-3,去除npc攻击造成的伤血记录
- if summonOwner != None:
-
- # 召唤兽主人为玩家,伤血
- if summonOwner.GetGameObjType() == IPY_GameWorld.gotPlayer:
- AttackCommon.NPCAddObjInHurtList(summonOwner, curTagNPC, curTagNPCHPBeforeAtk, hurtHP)
-
- addAngry = hurtHP
- if skill != None:
- addAngry += skill.GetSkillAngry()
-
- #也添加一份主人的仇恨(暴风雪这类的不可攻击召唤技能, 要NPC攻击主人)
- curTagNPCControl.AddObjToAngryList(summonOwner, addAngry)
-
- #---构建伤血列表---
-
- #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
- AttackCommon.AddHurt(curTagNPC, skillHurtList, hurtType.HurtType, hurtHP)
- #ChNPC.OnUndeathBossHurt(curTagNPC, hurtHP)
- return hurtType
-#---------------------------------------------------------------------
-## 处理攻击后的结果
-# @param curNormalNPC 攻击方:召唤兽
-# @param curTagPlayer 防守方:普通NPC
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return 无意义
-# @remarks 处理攻击后的结果
-def AttackResult(curSummonNPC, curTagNPC, skill, tick):
-
- if ChNPC.OnUndeathBossAttacked(curTagNPC):
- return
-
- #---NPC还活着---
- if GameObj.GetHP(curTagNPC) > 0:
- ChNPC.OnNPCAttacked(curSummonNPC, curTagNPC, skill, tick)
- return
-
- #---NPC被击杀---
- if TurnAttack.SetTurnObjKilled(curTagNPC, curSummonNPC):
- return
-
- #玩家击杀NPC副本触发器
- curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC)
-
- if not ChNPC.OnCheckCanDie(curPlayer, curTagNPC, skill, tick):
- return
-
- #2011-05-12 chenxuewei 有没主人都只要通知一次即可,避免重复通知
- if curPlayer != None:
- NPCCommon.OnPlayerAttackNPCDie(curTagNPC, curPlayer, skill)
- FBLogic.DoFB_Player_KillNPC(curPlayer, curTagNPC, tick)
- else:
- #副本
- FBLogic.DoFB_Npc_KillNPC(curSummonNPC, curTagNPC, tick)
-
- #调用统一击杀逻辑
- curTagNPCControl = NPCCommon.NPCControl(curTagNPC)
- curTagNPCControl.SetKilled()
- return
-#---------------------------------------------------------------------
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_Pet.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_Pet.py
deleted file mode 100644
index 7c34c5a..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_Pet.py
+++ /dev/null
@@ -1,146 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package SummonNPC_Attack_Pet
-# 召唤兽攻击宠物
-#
-# @author chenxuewei
-# @date 2010-06-26
-# @version 1.5
-#
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-09-27 17:55" panwei 取消GM不可攻击限制
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2012-06-13 18:00" jiang 攻击宠物玩家红名
-# @change: "2016-02-26 17:00" hxp 增加PVP伤害统计
-#------------------------------------------------------------------------------
-"""Version = 2016-02-26 17:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import AttackCommon
-import ChConfig
-import IPY_GameWorld
-import GameWorld
-import PlayerControl
-import PetControl
-import SkillShell
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击
-# @param curSummonNPC 攻击方:召唤兽
-# @param curTagPet 防守方:宠物
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True or False
-# @remarks 是否可以攻击
-def GetCanAttack(curSummonNPC, curTagPet, skill, tick):
- return False
- #return AttackCommon.CheckNPCCanAttackTag(curSummonNPC, curTagPet, skill)
-
-## 获得关系
-# @param curNormalNPC 攻击方:召唤兽
-# @param curTagPet 防守方:宠物
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-# @remarks 获得关系
-def GetTagRelation(curSummonNPC, curTagPet, skill, tick):
- return ChConfig.Type_Relation_None , ChConfig.Def_PASysMessage_None
-
- #获得召唤兽的主人
- curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC)
-
- if curPlayer == None:
- #该召唤兽的主人非玩家,则可攻击宠物
-# curSummonOwner_NPC = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotNPC,curSummonNPC)
- return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
- curTagPlayer = PetControl.GetPetOwner(curTagPet) # 宠物主人
-
- if curTagPlayer != None:
- #同一玩家不互相攻击
- if GameWorld.IsSameObj(curPlayer, curTagPlayer):
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-
- #检查攻击模式
- if not AttackCommon.CheckPlayerAttackMode_Player(curPlayer, curTagPlayer):
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_AttackMode
-
- #------------------------以下逻辑,都是玩家可以攻击目标的情况下
-
- return AttackCommon.GetPlayersRelation(curPlayer, curTagPlayer)
-
- #不同类型的,可以直接攻击
- return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
-
-## 攻击
-# @param curSummonNPC 攻击方:召唤兽
-# @param curTagPet 防守方:宠物
-# @param skill 技能(无->None)
-# @param skillValue 技能增强
-# @param skillPercent 技能增强百分比
-# @param skillHurtList 技能伤血列表(C++接口)
-# @param tick 当前时间
-# @return hurtType : HurtType 伤害结构体类
-# @remarks 攻击
-def DoAttack(curSummonNPC, curTagPet, skill, skillValue, skillPercent, skillHurtList, tick):
-
- hurtType = AttackCommon.GetHurtHP(curSummonNPC, curTagPet, skill,
- skillValue, skillPercent, tick)
- hurtHP = hurtType.HurtHP
- #添加仇恨
- petControl = NPCCommon.NPCControl(curTagPet)
- petControl.AddObjDetelToAngryList_ByAttack(curSummonNPC, hurtHP, skill)
-
- #---攻击方为召唤兽,给主人加仇恨---
- summonOwner = NPCCommon.GetSummonOwnerDetel(curSummonNPC)
-
- if summonOwner != None:
- petControl.AddObjToAngryList(summonOwner, 1)
-
- curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC)
- curTagPlayer = PetControl.GetPetOwner(curTagPet) # 宠物主人
- if curPlayer != None and curTagPlayer != None:
- AttackCommon.OnPVPDamage(curPlayer, hurtHP, curTagPlayer, "Summon v Pet")
-
- #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
- AttackCommon.AddHurt(curTagPet, skillHurtList, hurtType.HurtType, hurtHP)
- return hurtType
-
-## 处理攻击后的结果
-# @param curSummonNPC 攻击方:召唤兽
-# @param curTagPet 防守方:宠物
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True
-# @remarks 处理攻击后的结果
-def AttackResult(curSummonNPC, curTagPet, skill, tick):
-
- curTagPlayer = PetControl.GetPetOwner(curTagPet) # 宠物主人
-
- #获取召唤兽的主人
- curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC)
-
- if curTagPlayer != None and GameObj.GetHP(curTagPlayer) > 0:
- #进入战斗状态
- AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
-
- #是否在特殊的副本中
- if curPlayer != None:
- AttackCommon.OnPlayerHitPlayer(curPlayer, curTagPlayer, tick)
-
- #宠物死亡
- if GameObj.GetHP(curTagPet) <= 0:
- curTagPetNPCControl = NPCCommon.NPCControl(curTagPet)
- curTagPetNPCControl.SetKilled()
-
- if curPlayer != None and curTagPlayer != None:
- AttackCommon.AddPKValue(curPlayer, curTagPlayer, tick)
-
- return True
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_Player.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_Player.py
deleted file mode 100644
index e3e790f..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_Player.py
+++ /dev/null
@@ -1,163 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package SummonNPC_Attack_Player
-# 召唤兽攻击玩家
-#
-# @author eggxp
-# @date 2010-4-20
-# @version 1.7
-#
-# 修改时间 修改人 修改内容
-# @change: "2013-03-25 10:00" wdb 去装备使用不扣耐久
-# @change: "2013-09-27 19:30" Alee 恢复耐久
-# @change: "2013-11-05 21:00" Alee PK提示
-# @change: "2014-03-08 17:20" hxp 修复召唤兽击杀红/黄名玩家时,召唤兽主人红名问题
-# @change: "2016-02-26 17:00" hxp 增加PVP伤害统计
-# @change: "2016-11-24 19:30" hxp 支持特殊副本攻击结果判断死亡规则
-# @change: "2016-11-26 19:00" hxp 陷阱AI增加可攻击主人逻辑
-#------------------------------------------------------------------------------
-#"""Version = 2016-11-26 19:00"""
-#------------------------------------------------------------------------------
-import FBLogic
-import NPCCommon
-import PlayerControl
-import IPY_GameWorld
-import AttackCommon
-import ChConfig
-import GameWorld
-import BaseAttack
-import ChEquip
-import SkillShell
-import ChNPC
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击
-# @param curNormalNPC 攻击方:召唤兽
-# @param curTagPlayer 防守方:玩家
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True or False
-# @remarks 是否可以攻击
-def GetCanAttack(curSummonNPC, curTagPlayer, skill, tick):
- return AttackCommon.CheckNPCCanAttackTag(curSummonNPC, curTagPlayer, skill)
-
-## 获得关系
-# @param curNormalNPC 攻击方:召唤兽
-# @param curTagPlayer 防守方:玩家
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-# @remarks 获得关系
-def GetTagRelation(curSummonNPC, curTagPlayer, skill, tick):
- #召唤兽的主人(玩家)
- summonOwner = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC)
- if summonOwner == None :
- #NPC的召唤兽不考虑
- return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
- #人物的召唤兽,不能攻击自己的主人
- if GameWorld.IsSameObj(summonOwner, curTagPlayer) :
- #return ChNPC.OnGetOwnerRelation(curSummonNPC, curTagPlayer)
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-
- #判断主人的攻击模式,判断是否可以攻击这个玩家
- if not AttackCommon.CheckPlayerAttackMode_Player(summonOwner, curTagPlayer):
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_AttackMode
-
- #------------------------以下逻辑,都是玩家可以攻击目标的情况下
-
- return AttackCommon.GetPlayersRelation(summonOwner, curTagPlayer)
-
-
-## 攻击
-# @param curNormalNPC 攻击方:召唤兽
-# @param curTagPlayer 防守方:玩家
-# @param skill 技能(无->None)
-# @param skillValue 技能增强
-# @param skillPercent 技能增强百分比
-# @param skillHurtList 技能伤血列表(C++接口)
-# @param tick 当前时间
-# @return hurtType : HurtType 伤害结构体类
-# @remarks 攻击
-def DoAttack(curSummonNPC, curTagPlayer, skill, skillValue, skillPercent, skillHurtList, tick):
-
- curTagPlayerHPBeforeAtk = GameObj.GetHP(curTagPlayer)
-
- hurtType = AttackCommon.GetHurtHP(curSummonNPC, curTagPlayer, skill,
- skillValue, skillPercent, tick)
- #伤血
- hurtHP = hurtType.HurtHP
-
- curAttackPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC)
- #2个玩家的召唤兽互相PK,需要判断防守方玩家的是否可以攻击进攻方
- if curAttackPlayer != None:
- if AttackCommon.CheckPlayerAttackMode_Player(curTagPlayer, curAttackPlayer):
- AttackCommon.SummonAddAngryByOwner(curSummonNPC, curTagPlayer, hurtHP)
-
- #AttackCommon.NPCAddObjInHurtList(curAttackPlayer, curTagPlayer, curTagPlayerHPBeforeAtk, hurtHP)
-
- AttackCommon.OnPVPDamage(curAttackPlayer, hurtHP, curTagPlayer, "Summon v Player")
-
- #直接攻击
- else:
- AttackCommon.SummonAddAngryByOwner(curSummonNPC, curTagPlayer, hurtHP)
-
- #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
- AttackCommon.AddHurt(curTagPlayer, skillHurtList, hurtType.HurtType, hurtHP)
- return hurtType
-
-
-## 处理攻击后的结果
-# @param curNormalNPC 攻击方:召唤兽
-# @param curTagPlayer 防守方:玩家
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True
-# @remarks 处理攻击后的结果
-def AttackResult(curSummonNPC, curTagPlayer, skill, tick):
- #防守方血量
- curTagPlayerHP = GameObj.GetHP(curTagPlayer)
- curTagPlayerFBHP = FBLogic.OnGetFBCurHP(curTagPlayer)
-
- #是否同国籍
- #获得攻击方拥有者
- curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC)
-
- #被攻击提示,避免频繁提示
- #===========================================================================
- # if not curTagPlayer.GetBattleState():
- # PlayerControl.NotifyCode(curTagPlayer, "PK_admin_0")
- #
- # if curPlayer != None and not curPlayer.GetBattleState():
- # PlayerControl.NotifyCode(curTagPlayer, "PK_admin_0")
- #===========================================================================
-
- #玩家是否死亡
- if curTagPlayerHP > 0 and curTagPlayerFBHP > 0:
- #被攻击者也进入战斗状态
- AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
-
- #是否在特殊的副本中
- if curPlayer != None:
- AttackCommon.OnPlayerHitPlayer(curPlayer, curTagPlayer, tick)
-
- return
-
- if curPlayer != None:
- #执行玩家击杀玩家逻辑
- AttackCommon.OnPlayerKillPlayer(curPlayer, curTagPlayer, tick)
-
- #刷新NPC的仇恨列表,删除死亡对象
- npcControl = NPCCommon.NPCControl(curSummonNPC)
- npcControl.RefreshAngryList(tick)
-
- #玩家已经死亡
- tagPlayerControl = PlayerControl.PlayerControl(curTagPlayer)
- tagPlayerControl.SetDead()
- return True
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_SummonNPC.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_SummonNPC.py
deleted file mode 100644
index b298f0b..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_SummonNPC.py
+++ /dev/null
@@ -1,165 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package SummonNPC_Attack_SummonNPC
-# 召唤兽攻击召唤兽
-#
-# @author eggxp
-# @date 2010-4-20
-# @version 1.9
-#
-# 修改时间 修改人 修改内容
-# @change: "2010-05-12 18:30" zhengyang 添加注释
-# @change: "2010-05-28 15:50" chenxuewei 应策划刘鸿生需求:增加剑圣项目的PK规则
-# @change: "2010-06-02 10:50" chenxuewei 玩家可以攻击目标的情况下,获得玩家间的关系统一在AttackCommon处理
-# @change: "2010-06-07 13:30" Alee 召唤兽攻击给主人加仇恨
-# @change: "2010-06-07 17:30" Alee 调用已有的管理器
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-09-27 17:55" panwei 取消GM不可攻击限制
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2016-02-26 17:00" hxp 增加PVP伤害统计
-#------------------------------------------------------------------------------
-"""Version = 2016-02-26 17:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import AttackCommon
-import ChConfig
-import IPY_GameWorld
-import GameWorld
-import PlayerControl
-import SkillShell
-import TurnAttack
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击
-# @param curNormalNPC 攻击方:召唤兽
-# @param curTagPlayer 防守方:召唤兽
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True or False
-# @remarks 是否可以攻击
-def GetCanAttack(curSummonNPC, curTagSummon, skill, tick):
- return AttackCommon.CheckNPCCanAttackTag(curSummonNPC, curTagSummon, skill)
-
-## 获得关系
-# @param curNormalNPC 攻击方:召唤兽
-# @param curTagPlayer 防守方:召唤兽
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-# @remarks 获得关系
-def GetTagRelation(curSummonNPC, curTagSummon, skill, tick):
- #变量初始化
- curSummonOwner_NPC = None
- curTagSummonOwner_NPC = None
-
- #获得2个召唤兽的主人
- curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC)
-
- if curPlayer == None :
- curSummonOwner_NPC = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotNPC, curSummonNPC)
-
- curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummon)
-
- if curTagPlayer == None :
- curTagSummonOwner_NPC = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotNPC, curTagSummon)
-
- if curSummonOwner_NPC != None and curTagSummonOwner_NPC != None :
- #NPC的召唤兽不互相攻击
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-
- if curPlayer != None and curTagPlayer != None :
- #私有木桩只能自己打自己的
- if curTagSummon.GetType() in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:
- summonPlayerID = curTagSummon.GetDictByKey(ChConfig.Def_NPC_Dict_PriWoodPilePlayerID)
- if curPlayer.GetPlayerID() != summonPlayerID:
- 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
-
-
- #检查攻击模式
- if not AttackCommon.CheckPlayerAttackMode_Player(curPlayer, curTagPlayer):
- return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_AttackMode
-
- #------------------------以下逻辑,都是玩家可以攻击目标的情况下
-
- return AttackCommon.GetPlayersRelation(curPlayer, curTagPlayer)
-
- #不同类型的,可以直接攻击
- return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
-
-## 攻击
-# @param curNormalNPC 攻击方:召唤兽
-# @param curTagPlayer 防守方:召唤兽
-# @param skill 技能(无->None)
-# @param skillValue 技能增强
-# @param skillPercent 技能增强百分比
-# @param skillHurtList 技能伤血列表(C++接口)
-# @param tick 当前时间
-# @return hurtType : HurtType 伤害结构体类
-# @remarks 攻击
-def DoAttack(curSummonNPC, curTagSummon, skill, skillValue, skillPercent, skillHurtList, tick):
- hurtType = AttackCommon.GetHurtHP(curSummonNPC, curTagSummon, skill,
- skillValue, skillPercent, tick)
- hurtHP = hurtType.HurtHP
- #添加仇恨
- summonControl = NPCCommon.NPCControl(curTagSummon)
- summonControl.AddObjDetelToAngryList_ByAttack(curSummonNPC, hurtHP, skill)
-
- #---攻击方为召唤兽,给主人加仇恨---
- summonOwner = NPCCommon.GetSummonOwnerDetel(curSummonNPC)
-
- if summonOwner != None:
- summonControl.AddObjToAngryList(summonOwner, 1)
-
- curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC)
- curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummon)
- if curPlayer != None and curTagPlayer != None:
- AttackCommon.OnPVPDamage(curPlayer, hurtHP, curTagPlayer, "Summon v Summon")
-
-
- #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
- AttackCommon.AddHurt(curTagSummon, skillHurtList, hurtType.HurtType, hurtHP)
- return hurtType
-
-
-## 处理攻击后的结果
-# @param curNormalNPC 攻击方:召唤兽
-# @param curTagPlayer 防守方:召唤兽
-# @param skill 技能(无->None)
-# @param tick 当前时间
-# @return True
-# @remarks 处理攻击后的结果
-def AttackResult(curSummonNPC, curTagSummon, skill, tick):
- #获取防守方召唤兽的主人
- curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummon)
- #攻击的是玩家的召唤兽
- if curTagPlayer != None and GameObj.GetHP(curTagPlayer) > 0:
- #进入战斗状态
- AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
- #获取召唤兽的主人
- curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC)
-
- #是否在特殊的副本中
- if curPlayer != None:
- AttackCommon.OnPlayerHitPlayer(curPlayer, curTagPlayer, tick)
-
- #防守方召唤兽死亡
- if GameObj.GetHP(curTagSummon) <= 0:
- if TurnAttack.SetTurnObjKilled(curTagSummon, curSummonNPC):
- return
- curTagSummonNPCControl = NPCCommon.NPCControl(curTagSummon)
- #召唤兽死亡
- curTagSummonNPCControl.SetKilled()
-
- return True
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BaseAttack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BaseAttack.py
index c5ef889..da07209 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BaseAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BaseAttack.py
@@ -340,7 +340,7 @@
DoLogic_AttackResult(attacker, defender, useSkill, tick)
- TurnAttack.OnTurnfightAttackResult(attacker, defender, useSkill)
+ #TurnAttack.OnTurnfightAttackResult(attacker, defender, useSkill)
return True
#---------------------------------------------------------------------
@@ -666,7 +666,7 @@
OnHurtTypeTriggerPassiveSkill(attacker, defender, curSkill, tick)
DoLogic_AttackResult(attacker, defender, curSkill, tick)
- TurnAttack.OnTurnfightAttackResult(attacker, defender, curSkill)
+ #TurnAttack.OnTurnfightAttackResult(attacker, defender, curSkill)
return True
@@ -878,7 +878,7 @@
DoLogic_AttackResult(attacker, defObj, curSkill, tick)
- TurnAttack.OnTurnfightAttackResult(attacker, defender, curSkill)
+ #TurnAttack.OnTurnfightAttackResult(attacker, defender, curSkill)
return
## 执行群攻攻击
@@ -1882,7 +1882,7 @@
#通知客户端攻击结果
__Sync_AttackResult(curNPC, target, curSkill)
- TurnAttack.OnTurnfightAttackSuccess(curNPC, target, curSkill)
+ #TurnAttack.OnTurnfightAttackSuccess(curNPC, target, curSkill)
#技能使用成功
if curSkill:
@@ -2671,7 +2671,7 @@
DoLogic_AttackResult(attacker, defObj, curSkill, tick)
- TurnAttack.OnTurnfightAttackResult(attacker, None, curSkill)
+ #TurnAttack.OnTurnfightAttackResult(attacker, None, curSkill)
return True
@@ -2781,7 +2781,7 @@
sendPack.ValueEx = curHurt.GetHurtHPEx()
sendPack.RemainHP = curHurt.GetCurHP()
sendPack.RemainHPEx = curHurt.GetCurHPEx()
- turnFight = TurnAttack.GetTurnFightMgr().getNPCTurnFight(attacker.GetID())
+ turnFight = TurnAttack.GetTurnFightMgr().getTurnFight(attacker.GetTFGUID())
if turnFight:
turnFight.addBatPack(sendPack)
return
@@ -2797,7 +2797,7 @@
# m_LastBattleTick = GetGameWorldManager()->GetTick();
#===========================================================================
- turnFight = TurnAttack.GetTurnFightMgr().getNPCTurnFight(attacker.GetID())
+ turnFight = TurnAttack.GetTurnFightMgr().getTurnFight(attacker.GetTFGUID())
if turnFight:
sendPack = ChNetSendPack.tagUseSkillAttack()
sendPack.ObjID = attacker.GetID()
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py
new file mode 100644
index 0000000..2b7da00
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py
@@ -0,0 +1,578 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package BattleObj
+#
+# @todo:战斗对象
+# @author hxp
+# @date 2025-08-06
+# @version 1.0
+#
+# 详细描述: py自定义的战斗对象,可以是玩家、NPC通用的,废弃原c++的Player及NPC,完全由py自行处理
+# MMO项目可以curPlayer绑定一个战斗对象,curPlayer仅做为玩家的数据对象,战斗相关统一使用战斗对象
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-08-06 18:30"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import PyGameData
+import TurnAttack
+import IpyGameDataPY
+import ChNetSendPack
+import ShareDefine
+import ChConfig
+import ObjPool
+
+class HurtObj():
+ ## 伤血统计
+
+ def __init__(self):
+ self.Clear()
+ return
+
+ def Clear(self):
+ self._objID = 0
+ self._hurtTypes = 0 # 本次伤血类型,如闪避、暴击、格挡等,通过二进制或运算得到最终值,支持多种同时出现,如暴击的同时被格挡
+ self._hurtHP = 0 # 伤血值
+ self._lostHP = 0 # 实际掉血值
+ self._curHP = 0 # 更新血量
+ self._suckHP = 0 # 吸血量
+ self._bounceHP = 0 # 反弹血量
+ return
+
+ def GetObjID(self): return self._objID
+ def SetObjID(self, objID): self._objID = objID
+ def GetHurtTypes(self): return self._hurtTypes
+ def SetHurtTypes(self, hurtTypes): self._hurtTypes = hurtTypes
+ def AddHurtType(self, hurtType):
+ ## 添加伤血类型,单次伤害支持多种类型同时出现
+ self._hurtTypes |= pow(2, hurtType)
+ return
+ def HaveHurtType(self, hurtType):
+ ## 判断是否存在某种伤血类型
+ return self._hurtTypes&pow(2, hurtType)
+ def GetHurtHP(self): return self._hurtHP
+ def SetHurtHP(self, hurtHP): self._hurtHP = hurtHP
+ def GetLostHP(self): return self._lostHP
+ def SetLostHP(self, lostHP): self._lostHP = lostHP
+ def GetCurHP(self): return self._curHP
+ def SetCurHP(self, curHP): self._curHP = curHP
+ def GetSuckHP(self): return self._suckHP
+ def SetSuckHP(self, suckHP): self._suckHP = suckHP
+ def GetBounceHP(self): return self._bounceHP
+ def SetBounceHP(self, bounceHP): self._bounceHP = bounceHP
+
+class PyBuff():
+
+ def __init__(self, skillData):
+ self._skillData = skillData
+ self._buffID = 0
+ self._ownerID = 0
+ self._layer = 0
+ self._remainTime = 0
+ self._valueList = []
+ return
+
+ def GetSkillData(self): return self._skillData
+ def GetSkillID(self): return self._skillData.GetSkillID()
+ def GetBuffID(self): return self._buffID
+ def SetBuffID(self, buffID): self._buffID = buffID
+ def GetOwnerID(self): return self._ownerID
+ def SetOwnerID(self, ownerID): self._ownerID = ownerID
+ def GetLayer(self): return self._layer
+ def SetLayer(self, layer): self._layer = layer
+ def GetRemainTime(self): return self._remainTime
+ def SetRemainTime(self, remainTime): self._remainTime = remainTime
+ def SetValueList(self, valueList): self._valueList = valueList
+ def GetValue(self, index):
+ return self._valueList[index] if len(self._valueList) > index else 0
+
+class BuffManager():
+ ## 战斗对象buff管理器
+
+ def __init__(self):
+ self._buffList = [] # [PyBuff, ...]
+ self._buffIDDict = {} # {buffID:PyBuff, ...}
+ self._skillTypeIDBuffIDs = {} # 技能TypeID对应的buff {skillTypeID:[buffID, ...], ...}
+ self._buffID = 0 # 该对象的唯一buffID,递增,不同对象buffID可重复,buffID非skillID,不同buffID的skillID可能一样
+ # 该项目设定同一个对象可能同时存在多个相同skillID的buff,独立算CD
+ return
+
+ def ClearBuff(self):
+ poolMgr = ObjPool.GetPoolMgr()
+ for buff in self._buffList:
+ poolMgr.release(buff)
+ self._buffList = []
+ self._buffIDDict = {}
+ self._skillTypeIDBuffIDs = {}
+ self._buffID = 0
+ return
+
+ def GetBuffCount(self): return len(self._buffList)
+ def GetBuffByIndex(self, index):
+ buff = self._buffList[index]
+ #if False:
+ # buff = PyBuff()
+ return buff
+
+ def AddBuff(self, skillID):
+ buff = None
+ skillData = IpyGameDataPY.GetIpyGameData("Skill", skillID)
+ if not skillData:
+ return buff
+ skillTypeID = skillData.GetSkillTypeID()
+ self._buffID += 1
+
+ buff = ObjPool.GetPoolMgr().acquire(PyBuff, skillData)
+ buff.SetBuffID(self._buffID)
+
+ self._buffList.append(buff)
+ self._buffIDDict[self._buffID] = buff
+ if skillTypeID not in self._skillTypeIDBuffIDs:
+ self._skillTypeIDBuffIDs[skillTypeID] = []
+ buffIDs = self._skillTypeIDBuffIDs[skillTypeID]
+ if self._buffID not in buffIDs:
+ buffIDs.append(self._buffID)
+
+ #if False:
+ # buff = PyBuff()
+ return buff
+
+ def GetBuff(self, buffID):
+ buff = None
+ if buffID in self._buffIDDict:
+ buff = self._buffIDDict[buffID]
+ #if False:
+ # buff = PyBuff()
+ return buff
+
+ def FindBuffIDBySkillID(self, skillID):
+ ## 返回该技能ID的所有buffID列表
+ skillData = IpyGameDataPY.GetIpyGameData("Skill", skillID)
+ if not skillData:
+ return []
+ return self.FindBuffIDBySkillTypeID(skillData.GetSkillTypeID())
+ def FindBuffIDBySkillTypeID(self, skillTypeID):
+ ## 返回该技能TypeID的所有buffID列表
+ if skillTypeID not in self._skillTypeIDBuffIDs:
+ return []
+ buffs = []
+ for buffID in self._skillTypeIDBuffIDs[skillTypeID]:
+ if buffID not in self._buffIDDict:
+ continue
+ buffs.append(self._buffIDDict[buffID])
+ return buffs
+
+class PySkill():
+
+ def __init__(self, skillData):
+ self._skillData = skillData
+ self._remainTime = 0
+ self._batType = 0 # 战斗类型,普通、连击、反击、追击等
+ self._enhanceBySkill = None # 由哪个主技能触发的
+ self._tagObjList = [] # 本次技能目标列表 [BatObj, ...]
+ self._hurtList = [] # 本次伤血列表 [HurtObj, ...]
+ return
+
+ def SetSkillData(self, skillData): self._skillData = skillData
+ def GetSkillID(self): return self._skillData.GetSkillID()
+ def GetSkillTypeID(self): return self._skillData.GetSkillTypeID()
+ def GetSkillMaxLV(self): return self._skillData.GetSkillMaxLV()
+ def GetSkillName(self): return self._skillData.GetSkillName()
+ def GetFuncType(self): return self._skillData.GetFuncType()
+ def GetSkillType(self): return self._skillData.GetSkillType()
+ def GetHurtType(self): return self._skillData.GetHurtType()
+ def GetAtkType(self): return self._skillData.GetAtkType()
+ def GetTagAim(self): return self._skillData.GetTagAim() # 瞄准位置
+ def GetTagFriendly(self): return self._skillData.GetTagFriendly() # 敌我目标
+ def GetTagSelf(self): return self._skillData.GetTagSelf() # 是否含自己
+ def GetTagAffect(self): return self._skillData.GetTagAffect() # 目标细分
+ def GetTagCount(self): return self._skillData.GetTagCount() # 目标个数
+ def GetHappenRate(self): return self._skillData.GetHappenRate() # 释放或添加几率
+ def GetLastTime(self): return self._skillData.GetLastTime() # 持续时间
+ def GetCoolDownTime(self): return self._skillData.GetCoolDownTime()
+ def FindEffectID(self, effID):
+ ## 查找是否有某个效果ID
+ # @return: 大于0该ID所在的效果ID编号; 0-不存在该效果ID
+ for idNum in range(1, 1 + 3):
+ if self.GetEffectID(idNum) == effID:
+ return idNum
+ return 0
+ def GetEffectID(self, idNum):
+ ## 获取效果ID
+ # @param idNum: 效果ID编号,从1开始
+ if idNum == 1:
+ return self._skillData.GetEffectID1()
+ if idNum == 2:
+ return self._skillData.GetEffectID2()
+ if idNum == 3:
+ return self._skillData.GetEffectID3()
+ return 0
+ def GetEffectValue(self, idNum, index):
+ ## 获取效果对应值
+ # @param idNum: 效果ID编号,从1开始
+ # @param index: 值索引,从0开始代表第1个值
+ if idNum <= 0:
+ return 0
+ if idNum == 1:
+ values = self._skillData.GetEffectValues1()
+ elif idNum == 2:
+ values = self._skillData.GetEffectValues2()
+ elif idNum == 3:
+ values = self._skillData.GetEffectValues3()
+ else:
+ return 0
+ return values[index] if len(values) > index else 0
+ def GetConnSkill(self): return self._skillData.GetConnSkill() # 关联技能
+ def GetEnhanceSkillList(self): return self._skillData.GetEnhanceSkillList() # 额外触发的技能ID列表
+ def GetFightPower(self): return self._skillData.GetFightPower()
+
+ ## ---------------------------------- 非技能表内容 ----------------------------------
+ def GetRemainTime(self): return self._remainTime
+ def SetRemainTime(self, remainTime): self._remainTime = remainTime
+ def GetBatType(self): return self._batType
+ def SetBatType(self, batType): self._batType = batType
+ def GetEnhanceBySkill(self): return self._enhanceBySkill
+ def SetEnhanceBySkill(self, enhanceBySkill): self._enhanceBySkill = enhanceBySkill
+ def GetTagObjList(self): return self._tagObjList # 技能目标列表
+ def SetTagObjList(self, tagObjList): self._tagObjList = tagObjList
+ def ClearHurtObj(self):
+ ## 清空伤血统计
+ poolMgr = ObjPool.GetPoolMgr()
+ for hurtObj in self._hurtList:
+ poolMgr.release(hurtObj)
+ self._hurtList = []
+ return
+ def AddHurtObj(self, tagID):
+ ## 添加某个伤血
+ hurtObj = ObjPool.GetPoolMgr().acquire(HurtObj)
+ hurtObj.SetObjID(tagID)
+ self._hurtList.append(hurtObj)
+ return hurtObj
+ def GetHurtObjList(self): return self._hurtList
+ def GetHurtObj(self, tagID):
+ ## 获取某个伤血,如果目标没有在伤血列表里则返回None
+ for hurtObj in self._hurtList:
+ if hurtObj.GetObjID() == tagID:
+ return hurtObj
+ return
+
+class SkillManager():
+ ## 战斗对象技能管理器
+
+ def __init__(self):
+ self._skillList = [] # 技能列表 [PySkill, ...]
+ self._skillDict = {} # {skillID:PySkill, ...}
+ return
+
+ def SkillReset(self):
+ poolMgr = ObjPool.GetPoolMgr()
+ for skill in self._skillList:
+ poolMgr.release(skill)
+ self._skillList = []
+ self._skillDict = {}
+ return
+
+ def GetSkillCount(self): return len(self._skillList)
+ def GetSkillByIndex(self, index):
+ skill = self._skillList[index]
+ #if False:
+ # skill = PySkill()
+ return skill
+ def FindSkillByID(self, skillID):
+ skill = self._skillDict.get(skillID, None)
+ #if False:
+ # skill = PySkill()
+ return skill
+ def FindSkillByTypeID(self, skillTypeID):
+ skill = None
+ for s in self._skillList:
+ if s.GetSkillTypeID() == skillTypeID:
+ skill = s
+ break
+ #if False:
+ # skill = PySkill()
+ return skill
+
+ def LearnSkillByID(self, skillID):
+ skillData = IpyGameDataPY.GetIpyGameData("Skill", skillID)
+ if not skillData:
+ return
+ if skillID in self._skillDict:
+ return
+ skillTypeID = skillData.GetSkillTypeID()
+ curSkill = self.FindSkillByTypeID(skillTypeID)
+ if curSkill:
+ if curSkill.GetSkillID() >= skillID:
+ return
+ # 升级技能
+ curSkill.SetSkillData(skillData)
+ else:
+ # 学新技能
+ curSkill = ObjPool.GetPoolMgr().acquire(PySkill, skillData)
+ self._skillDict[skillID] = curSkill
+ self._skillList.append(curSkill)
+ return curSkill
+
+class BatObj():
+ ## 战斗实体对象数据,目前与某个NPCObj绑定
+
+ def __init__(self):
+ self.tfGUID = "" # 所属的某场回合战斗的guid
+ self.objID = 0
+ self.objName = ""
+ self.npcID = 0
+ self.ownerID = 0 # 所属玩家ID,可能为0,0代表非玩家的战斗实体
+ self.heroID = 0
+ self.skinID = 0
+ self.lv = 1
+ self.fightPower = 0
+ self.faction = 0 # 所属阵营,一般只有双方阵营, 1 或 2,发起方默认1
+ self.lineupNum = 1 # 阵容位置编号,一般多V多时有用,通常默认1
+ self.posNum = 0 # 所在阵容站位
+ self._initAttrDict = {} # 初始化时的属性,固定不变,初始化时已经算好的属性 {attrID:value, ...}
+ self._batAttrDict = {} # 实际战斗属性,包含buff层级的实际属性
+ self._skillTempAttrDict = {} # 某次技能释放中临时的属性增减 {attrID:+-value, ...}
+ self._kvDict = {} # 自定义kv字典
+ self._skillUseCntDict = {} # 技能累计使用次数 {skillID:useCnt, ...}
+ self._skillTurnUseCntDict = {} # 技能单回合累计使用次数 {skillID:useCnt, ...}
+ self._skillMgr = ObjPool.GetPoolMgr().acquire(SkillManager)
+ self._buffMgr = ObjPool.GetPoolMgr().acquire(BuffManager)
+
+ # 统计
+ self.hurtStat = 0 # 输出统计
+ self.defStat = 0 # 承伤统计
+ self.cureStat = 0 # 治疗统计
+ return
+
+ def InitBatAttr(self, initAttrDict, initXP=0):
+ ## 初始化战斗属性
+ self._initAttrDict = initAttrDict
+ self._batAttrDict = {}
+ self._batAttrDict.update(initAttrDict)
+ self._batAttrDict[ChConfig.AttrID_XP] = initXP
+ self._batAttrDict[ChConfig.AttrID_HP] = initAttrDict.get(ChConfig.AttrID_MaxHP, 1)
+ self._skillTempAttrDict = {}
+ return
+ def GetTFGUID(self): return self.tfGUID # 所属的某场战斗
+ def SetTFGUID(self, tfGUID): self.tfGUID = tfGUID
+ def GetTurnFight(self): return TurnAttack.GetTurnFightMgr().getTurnFight(self.tfGUID)
+ def GetID(self): return self.objID
+ def GetName(self): return self.objName
+ def SetName(self, name): self.objName = name
+ def GetNPCID(self): return self.npcID # 如果是NPC战斗单位,则该值非0
+ def SetNPCID(self, npcID): self.npcID = npcID # 设置所属的NPCID
+ def GetOwnerID(self): return self.ownerID # 如果是玩家战斗单位,则该值非0,为所属玩家ID
+ def GetHeroID(self): return self.heroID # 仅玩家有值,某个武将ID
+ def GetSkinID(self): return self.heroID # 仅玩家有值,武将皮肤
+ def SetOwnerHero(self, ownerID, heroID, skinID): # 设置所属的玩家及武将
+ self.ownerID = ownerID
+ self.heroID = heroID
+ self.skinID = skinID
+ def SetLineupPos(self, posNum, lineupNum=1):
+ ## 设置阵容所在位置
+ # @param posNum: 在本阵容中的站位
+ # @param lineupNum: 本阵容在本阵营中的站位,一般多V多时有用,默认1
+ self.posNum = posNum
+ self.lineupNum = lineupNum
+ def GetLineupNum(self): return self.lineupNum
+ def GetPosNum(self): return self.posNum
+ def GetFaction(self): return self.faction
+ def SetFaction(self, faction): self.faction = faction
+ def GetFightPower(self): return self.fightPower
+ def SetFightPower(self, fightPower): self.fightPower = fightPower
+ def GetLV(self): return self.lv
+ def SetLV(self, lv): self.lv = lv
+ def GetDictByKey(self, key): return self._kvDict.get(key, 0)
+ def SetDict(self, key, value): self._kvDict[key] = value
+
+ def GetSkillManager(self): return self._skillMgr
+ def GetBuffManager(self):return self._buffMgr
+
+ def GetCanAttack(self):
+ ## 可否被攻击
+ # 无敌buff
+ #if 无敌:
+ # return False
+ return True
+
+ # 战斗属性
+ def GetMaxHP(self): return self._batAttrDict.get(ChConfig.AttrID_MaxHP, 0)
+ def SetMaxHP(self, maxHP): self._batAttrDict[ChConfig.AttrID_MaxHP] = maxHP
+ def GetHP(self): return self._batAttrDict.get(ChConfig.AttrID_HP, 0)
+ def SetHP(self, hp, isNotify=False):
+ self._batAttrDict[ChConfig.AttrID_HP] = hp
+ if isNotify:
+ NotifyObjInfoRefresh(self, ChConfig.AttrID_HP, hp)
+ return
+ def SetHPFull(self, isNotify=True): self.SetHP(self.GetMaxHP())
+ def GetXP(self): return self._batAttrDict.get(ChConfig.AttrID_XP, 0)
+ def SetXP(self, xp, isNotify=True):
+ self._batAttrDict[ChConfig.AttrID_XP] = xp
+ if isNotify:
+ NotifyObjInfoRefresh(self, ChConfig.AttrID_XP, xp)
+ return
+ def GetAtk(self): return self.GetAttrValue(ChConfig.AttrID_Atk)
+ def GetDef(self): return self.GetAttrValue(ChConfig.AttrID_Def)
+
+ def GetAttrValue(self, attrID):
+ value = self._batAttrDict.get(attrID, 0)
+ if attrID in self._skillTempAttrDict:
+ value += self._skillTempAttrDict[attrID] # 支持正负值
+ value = max(1, value)
+ return value
+ def AddSkillTempAttr(self, attrID, value):
+ ## 增加技能临时属性,支持正负值
+ # @param value: 正值-加属性;负值-减属性
+ self._skillTempAttrDict[attrID] = self._skillTempAttrDict.get(attrID, 0) + value
+ def ClearSkillTempAttr(self): self._skillTempAttrDict = {}
+
+ def GetSkillUseCnt(self, skillID): return self._skillUseCntDict.get(skillID, 0)
+ def GetSkillTurnUseCnt(self, skillID): return self._skillTurnUseCntDict.get(skillID, 0)
+ def AddSkillUseCnt(self, skillID):
+ self._skillUseCntDict[skillID] = self._skillUseCntDict.get(skillID, 0) + 1
+ self._skillTurnUseCntDict[skillID] = self._skillTurnUseCntDict.get(skillID, 0) + 1
+
+ def StatHurtValue(self, hurtValue):
+ ## 统计输出
+ self.hurtStat += hurtValue
+ return self.hurtStat
+
+ def StatDefValue(self, lostHP):
+ ## 统计承伤
+ self.defStat += lostHP
+ return self.defStat
+
+ def StatCureValue(self, cureValue):
+ ## 统计治疗
+ self.cureStat += cureValue
+ return self.cureStat
+
+ def TurnReset(self):
+ ## 回合重置
+ self._skillTurnUseCntDict = {}
+
+ def ResetBatObj(self, isReborn=True):
+ ## 重置战斗相关
+ # @param isReborn: 死亡的是否复活
+
+ # 重置统计
+ self.hurtStat = 0
+ self.defStat = 0
+ self.cureStat = 0
+
+ if self.GetHP() <= 0 and not isReborn:
+ return
+
+ # 清除buff
+
+ # 回满血
+ self.SetHPFull()
+
+ # 重置怒气
+ initXP = IpyGameDataPY.GetFuncCfg("AngerXP", 1)
+ self.SetXP(initXP)
+ return
+
+
+class BattleObjMgr():
+ ## 战斗对象管理器
+
+ def __init__(self):
+ self._newID = 0 # 管理创建新的实例ID
+ self._freeIDList = []
+ self.batObjDict = {} # 战斗单位 {objID:BatObj, ...}
+ return
+
+ def __getNewObjID(self):
+ while self._freeIDList:
+ objID = self._freeIDList.pop(0)
+ if objID not in self.batObjDict:
+ return objID
+
+ maxID = 100000
+ if self._newID >= maxID:
+ self._newID = 0
+ while self._newID < maxID:
+ self._newID += 1
+ if self._newID not in self.batObjDict:
+ return self._newID
+ GameWorld.ErrLog("__getNewObjID error.")
+ return 0
+
+ def addBatObj(self):
+ ## 添加战斗单位
+ newBatObj = None
+ newObjID = self.__getNewObjID()
+ if not newObjID:
+ return newBatObj
+ newBatObj = ObjPool.GetPoolMgr().acquire(BatObj)
+ newBatObj.objID = newObjID
+ self.batObjDict[newObjID] = newBatObj
+ GameWorld.DebugLog("添加战斗单位: objID=%s" % (newObjID))
+ if False:
+ newBatObj = BatObj(None, 0)
+ return newBatObj
+
+ def getBatObj(self, objID):
+ batObj = None
+ if objID in self.batObjDict:
+ batObj = self.batObjDict[objID]
+ elif False:
+ batObj = BatObj(None, 0)
+ return batObj
+
+ def delBatObj(self, objID):
+ if objID not in self.batObjDict:
+ return
+ batObj = self.batObjDict.pop(objID)
+ if not batObj:
+ return
+ objID = batObj.objID
+ GameWorld.DebugLog("回收战斗单位: objID=%s" % (objID))
+ turnFight = batObj.GetTurnFight()
+ if turnFight:
+ # //04 07 NPC消失#tagNPCDisappear 此处通知消失,与回合制死亡区分
+ clientPack = ChNetSendPack.tagNPCDisappear()
+ clientPack.NPCID = [objID]
+ clientPack.Count = len(clientPack.NPCID)
+ turnFight.addBatPack(clientPack)
+
+ # 最后回收对象
+ ObjPool.GetPoolMgr().release(batObj)
+ if objID not in self._freeIDList: # 回收ID,重复利用
+ self._freeIDList.append(objID)
+ return
+
+def GetBatObjMgr():
+ batObjMgr = PyGameData.g_batObjMgr
+ if not batObjMgr:
+ batObjMgr = BattleObjMgr()
+ PyGameData.g_batObjMgr = batObjMgr
+ return batObjMgr
+
+def OnMinute():
+ GameWorld.Log("战斗单位数量: %s" % len(GetBatObjMgr().batObjDict))
+ return
+
+def NotifyObjInfoRefresh(batObj, attrID, value):
+ ##0418通知对象属性刷新
+ if attrID not in ChConfig.CDBRefresh_AttrIDDict:
+ return
+ refreshType, isBig = ChConfig.CDBRefresh_AttrIDDict[attrID]
+ turnFight = TurnAttack.GetTurnFightMgr().getTurnFight(batObj.GetTFGUID())
+ if not turnFight:
+ return
+ clientPack = ObjPool.GetPoolMgr().acquire(ChNetSendPack.tagObjInfoRefresh)
+ clientPack.ObjID = batObj.GetID()
+ clientPack.RefreshType = refreshType
+ if isBig:
+ clientPack.Value = value % ShareDefine.Def_PerPointValue
+ clientPack.ValueEx = value / ShareDefine.Def_PerPointValue
+ else:
+ clientPack.Value = value
+ clientPack.ValueEx = 0
+ turnFight.addBatPack(clientPack)
+ return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
index e1e95ad..1bc7528 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -31,12 +31,13 @@
import NPCCommon
import ShareDefine
import PyGameData
-import IPY_GameWorld
import ItemControler
import SkillCommon
-import SkillShell
import AttackCommon
-import FBLogic
+import BattleObj
+import TurnSkill
+import TurnBuff
+import ObjPool
import random
import time
@@ -55,129 +56,61 @@
FightState_Award, # 4 结算奖励
FightState_Over, # 5 结束状态,无特殊意义,仅代表所有处理结束了,与Start对应
) = range(6)
-
-Def_FactionA = 1
-Def_FactionB = 2
-
+
class BatLineup():
## 战斗阵容
- def __init__(self, faction, num, fightMgr):
- self.fightMgr = fightMgr
+ def __init__(self, faction, num, turnFight):
+ self.turnFight = turnFight # TurnFight
self.faction = faction # 所属阵营
self.num = num # 该阵容所在阵营中的编号,不同阵营可重复,多V多
self.ownerID = 0 # 阵容所属玩家ID,可能为0,0代表非玩家阵容
- self.npcPosDict = {} # 阵容NPC {站位编号:curNPC, ...}, 站位编号小于0为非主战单位,如主公、红颜等
- self.npcObjIDDict = {} # NPC实例ID字典 {objID:curNPC, ...}
self.shapeType = 0 # 阵型
- self.actionNum = ActionNumStart # 行动位置,从1开始
- self.lordAttrDict = {} # 主公属性
- self.npcAttrDict = {} # 阵容NPC属性 {npcID:{attrID:value, ...}, ...}
self.fightPower = 0 # 阵容总战力
-
- # 战斗统计
- self.hurtStatDict = {} # 输出统计 {objID:totalValue, ...}
- self.defStatDict = {} # 承伤统计 {objID:totalValue, ...}
- self.cureStatDict = {} # 治疗统计 {objID:totalValue, ...}
+ self.posObjIDDict = {} # 站位对应战斗实体 {站位编号:batObjID, ...}, 站位编号小于0为非主战单位,如主公、红颜等
+ self.actionNum = ActionNumStart # 行动位置,从1开始
return
- def getGUID(self): return self.fightMgr.guid
- def getPlayerID(self): return self.fightMgr.playerID # 发起的玩家ID
+ def getPlayerID(self): return self.turnFight.playerID # 发起的玩家ID
- def isEmpty(self): return not self.npcPosDict
+ def isEmpty(self): return not self.posObjIDDict
def setLineup(self, lineupInfo):
## 设置阵容
# @param lineupInfo: 阵容信息
self.clearLineup()
self.ownerID = lineupInfo.get("PlayerID", 0) # 阵容所属的玩家ID
- self.shapeType = lineupInfo.get("Shape", 0)
- self.lordAttrDict = lineupInfo.get("LordAttrDict", {})
+ self.shapeType = lineupInfo.get("ShapeType", 0)
+ self.fightPower = lineupInfo.get("FightPower", 0)
SummonLineupObjs(self, self.faction, self.num, lineupInfo, self.getPlayerID())
- return
-
- def refreshFightPower(self):
- ## 刷新阵容总战力
- if self.fightPower:
- return self.fightPower
-
- return self.fightPower
-
- def __resetStat(self):
- ## 重置战斗统计
- self.actionNum = ActionNumStart
- self.hurtStatDict = {}
- self.defStatDict = {}
- self.cureStatDict = {}
- return
-
- def __resetAttrState(self, isReborn=True):
- ## 重置属性状态
- # @param isReborn: 是否复活
- initXP = IpyGameDataPY.GetFuncCfg("AngerXP", 1)
- for curNPC in self.npcPosDict.values():
- if not curNPC:
- continue
- if GameObj.GetHP(curNPC) <= 0 and not isReborn:
- continue
- # 回满血,清除buff
- GameObj.SetHPFull(curNPC, False)
- # 重置怒气
- GameObj.SetXP(curNPC, initXP, False)
- # ...
-
return
def resetLineup(self, isReborn=True):
## 重置阵容
- self.__resetAttrState(isReborn)
- self.__resetStat()
+ batObjMgr = BattleObj.GetBatObjMgr()
+ for objID in self.posObjIDDict.values():
+ batObj = batObjMgr.getBatObj(objID)
+ if not batObj:
+ continue
+ batObj.ResetBatObj(isReborn)
return
def clearLineup(self):
## 清除阵容
- if not self.npcPosDict:
+ if not self.posObjIDDict:
return
- for curNPC in self.npcPosDict.values():
- if not curNPC:
- continue
- NPCCommon.SetDeadEx(curNPC)
- self.npcPosDict = {}
- self.npcObjIDDict = {}
- self.npcAttrDict = {}
+ batObjMgr = BattleObj.GetBatObjMgr()
+ for objID in self.posObjIDDict.values():
+ batObjMgr.delBatObj(objID)
+ self.posObjIDDict = {}
self.fightPower = 0
- self.__resetStat()
return
-
- def statHurtValue(self, objID, hurtValue):
- ## 统计输出
- if objID not in self.npcObjIDDict:
- return
- updValue = self.hurtStatDict.get(objID, 0) + hurtValue
- self.hurtStatDict[objID] = updValue
- return updValue
-
- def statDefValue(self, objID, lostHP):
- ## 统计承伤
- if objID not in self.npcObjIDDict:
- return
- updValue = self.defStatDict.get(objID, 0) + lostHP
- self.defStatDict[objID] = updValue
- return updValue
-
- def statCureValue(self, objID, cureValue):
- ## 统计治疗
- if objID not in self.npcObjIDDict:
- return
- updValue = self.cureStatDict.get(objID, 0) + cureValue
- self.cureStatDict[objID] = updValue
- return updValue
class BatFaction():
## 战斗阵营
- def __init__(self, faction, fightMgr):
- self.fightMgr = fightMgr
+ def __init__(self, faction, turnFight):
+ self.turnFight = turnFight # TurnFight
self.faction = faction
self.lineupDict = {} # 该阵营所有阵容信息 {编号:BatLineup, ...}
return
@@ -188,7 +121,7 @@
if num in self.lineupDict:
lineup = self.lineupDict[num]
else:
- lineup = BatLineup(self.faction, num, self.fightMgr)
+ lineup = BatLineup(self.faction, num, self.turnFight)
self.lineupDict[num] = lineup
return lineup
@@ -237,9 +170,6 @@
self.startTime = 0 # 开始时间戳,支持毫秒小数
self.costTime = 0 # 单场战斗总耗时,支持毫秒小数
-
- #玩家武将行动后击杀目标
- self.playerKillObjIDList = [] # [objID, ...]
return
def setTurn(self, mapID, funcLineID, turnMax, isNeedReport=False, msgDict={}):
@@ -281,7 +211,6 @@
if not lineupInfo:
continue
batLineup.setLineup(lineupInfo)
- batLineup.refreshFightPower()
return
def sortActionQueue(self):
@@ -290,7 +219,7 @@
for batFaction in self.factionDict.values():
faction = batFaction.faction
for num, batLineup in batFaction.lineupDict.items():
- fightPower = batLineup.refreshFightPower()
+ fightPower = batLineup.fightPower
sortValue = -(faction * 10 + num)
sortList.append([fightPower, sortValue, faction, num])
sortList.sort(reverse=True) # 战力高的先手
@@ -304,7 +233,7 @@
GameWorld.DebugLog("阵容行动顺序[f, n]: %s" % self.actionSortList)
return
- def getBatFaction(self, faction=Def_FactionA):
+ def getBatFaction(self, faction=ChConfig.Def_FactionA):
## 默认阵营1
batFaction = None
if faction in self.factionDict:
@@ -321,21 +250,25 @@
if self.winFaction:
return self.winFaction
+ batObjMgr = BattleObj.GetBatObjMgr()
for faction, batFaction in self.factionDict.items():
allKilled = True
for batLineup in batFaction.lineupDict.values():
if not allKilled:
break
- for posNum, curNPC in batLineup.npcPosDict.items():
+ for posNum, objID in batLineup.posObjIDDict.items():
if posNum <= 0:
# 非主战位置不判断
continue
- if GameObj.GetHP(curNPC) > 0:
+ batObj = batObjMgr.getBatObj(objID)
+ if not batObj:
+ continue
+ if batObj.GetHP() > 0:
allKilled = False
break
if allKilled:
- self.winFaction = Def_FactionA if faction == Def_FactionB else Def_FactionA
+ self.winFaction = ChConfig.Def_FactionA if faction == ChConfig.Def_FactionB else ChConfig.Def_FactionA
DoTurnFightOver(self.guid)
return self.winFaction
@@ -363,6 +296,8 @@
clientPack.Msg = msg
clientPack.Len = len(clientPack.Msg)
clientPack.FactionList = []
+
+ batObjMgr = BattleObj.GetBatObjMgr()
for faction in self.factionDict.keys():
batFaction = self.getBatFaction(faction)
tfFaction = ChPyNetSendPack.tagSCTurnFightFaction()
@@ -375,19 +310,22 @@
tfLineup.OwnerID = batLineup.ownerID
tfLineup.ShapeType = batLineup.shapeType
tfLineup.ObjList = []
- for posNum, curNPC in batLineup.npcPosDict.items():
+ for posNum, objID in batLineup.posObjIDDict.items():
+ batObj = batObjMgr.getBatObj(objID)
+ if not batObj:
+ continue
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()
- tfObj.MaxHPEx = curNPC.GetMaxHPEx()
- tfObj.LV = NPCCommon.GetNPCLV(curNPC)
+ tfObj.ObjID = batObj.GetID()
+ tfObj.NPCID = batObj.GetNPCID()
+ tfObj.HeroID = batObj.GetHeroID()
+ tfObj.SkinID = batObj.GetSkinID()
+ tfObj.HP = batObj.GetHP() % ChConfig.Def_PerPointValue
+ tfObj.HPEx = batObj.GetHP() / ChConfig.Def_PerPointValue
+ tfObj.MaxHP = batObj.GetMaxHP() % ChConfig.Def_PerPointValue
+ tfObj.MaxHPEx = batObj.GetMaxHP() / ChConfig.Def_PerPointValue
+ tfObj.LV = batObj.GetLV()
tfObj.PosNum = posNum
- tfObj.AngreXP = GameObj.GetXP(curNPC)
+ tfObj.AngreXP = batObj.GetXP()
tfLineup.ObjList.append(tfObj)
tfLineup.ObjCnt = len(tfLineup.ObjList)
tfFaction.LineupList.append(tfLineup)
@@ -411,7 +349,7 @@
self.addBatPack(clientPack)
return
- def syncObjAction(self, turnNum, objType, objID):
+ def syncObjAction(self, turnNum, objID):
clientPack = ChPyNetSendPack.tagMCTurnFightObjAction()
clientPack.Clear()
clientPack.TurnNum = turnNum
@@ -432,6 +370,8 @@
# 有玩家的统一每个包单独发送,同样也支持战报统计
if self.curPlayer:
NetPackCommon.SendFakePack(self.curPlayer, clientPack)
+ else:
+ ObjPool.GetPoolMgr().release(clientPack)
return
class TurnFightMgr():
@@ -439,7 +379,6 @@
def __init__(self):
self.turnFightDict = {} # {guid:TurnFight, ...}
- self.npcGUIDDict = {} # npc所属的某场战斗guid {objID:guid, ...}
return
def addTurnFight(self, mapID, funcLineID=0, playerID=0):
@@ -462,27 +401,6 @@
elif False:
tf = TurnFight()
return tf
-
- def getNPCTurnFight(self, objID):
- ## 获取NPC所在的回合战斗,如果该npc不属于某场回合战斗则返回None
- tf = None
- if objID in self.npcGUIDDict:
- guid = self.npcGUIDDict[objID]
- if guid in self.turnFightDict:
- tf = self.turnFightDict[guid]
- if not tf and False:
- tf = TurnFight()
- return tf
-
- def setNPCGUID(self, objID, guid):
- ## 设置NPC所属回合战斗guid
- self.npcGUIDDict[objID] = guid
- GameWorld.DebugLog("设置NPC所属回合战斗guid: %s,%s" % (objID, guid))
- return
- def delNPCGUID(self, objID):
- guid = self.npcGUIDDict.pop(objID, None)
- GameWorld.DebugLog("删除NPC所属回合战斗guid: %s,%s" % (objID, guid))
- return
def GetTurnFightMgr():
tfMgr = None
@@ -513,10 +431,6 @@
## 当前战斗是否关卡boss
return self.turnFight.mapID == ChConfig.Def_FBMapID_MainBoss
- def clear(self):
- self.turnFight.clearFight()
- return
-
def GetMainFightMgr(curPlayer):
## 获取主线战斗管理
olPlayer = PlayerOnline.GetOnlineMgr().GetOnlinePlayer(curPlayer)
@@ -532,71 +446,50 @@
% (chapterID, levelNum, nowChapterID, fixNowValue), curPlayer.GetPlayerID())
return
-def GetPlayerLineupByCache(playerID, lineupID):
+def GetPlayerLineupInfoByCache(playerID, lineupID):
## 获取玩家阵容信息 - 根据玩家查看缓存
- return {}
+ lineupInfo = {}
+ return lineupInfo
-def GetPlayerLineup(curPlayer, lineupID):
- ## 获取玩家阵容信息
+def GetPlayerLineupInfo(curPlayer, lineupID):
+ ## 获取玩家阵容信息,可用于战斗或查看缓存,因为可能取玩家的缓存进行对战,所以统一使用json格式,前端通用
# @param lineupID: 阵容ID
# @return: 阵容全部信息json字典,前端通用格式
playerID = curPlayer.GetPlayerID()
+ lineup = PlayerOnline.GetOnlinePlayer(curPlayer).GetLineup(lineupID)
- # 武将
+ lineupInfo = {"PlayerID":playerID, "FightPower":lineup.fightPower, "ShapeType":lineup.shapeType}
heroDict = {}
- heroCount = 0
curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptHero)
- for index in range(curPack.GetCount()):
- heroItem = curPack.GetAt(index)
- if not heroItem or heroItem.IsEmpty():
- continue
- lineupCount = heroItem.GetUserAttrCount(ShareDefine.Def_IudetHeroLineup)
- if not lineupCount:
- continue
- posNum = 0 # 站位
- for lpIndex in range(lineupCount):
- lineupValue = heroItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroLineup, lpIndex)
- #阵容类型*10000+阵型类型*100+位置编号
- if lineupValue / 10000 != lineupID:
- continue
- posNum = lineupValue % 100
- break
-
- if not posNum:
- continue
-
- heroID = heroItem.GetItemTypeID()
- heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
- if not heroIpyData:
- continue
- skinIDList = heroIpyData.GetSkinIDList()
- skinIndex = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroSkin)
- if skinIndex < 0 or skinIndex >= len(skinIDList):
- continue
- skinID = skinIDList[skinIndex]
+ for posNum in lineup.lineupHeroDict.keys():
+ hero = lineup.GetLineupHero(posNum)
+ heroID = hero.heroID
+ itemIndex = hero.itemIndex
+ userData = ""
+ heroLV = 1
+ if itemIndex >= 0 and itemIndex < curPack.GetCount():
+ heroItem = curPack.GetAt(itemIndex)
+ if heroItem and not heroItem.IsEmpty():
+ userData = heroItem.GetUserData()
+ heroLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroLV)
+
+ skillIDlist = []
+ skillIDlist += hero.heroSkillIDList
heroDict[str(posNum)] = {
"HeroID":heroID,
- "SkinID":skinID,
- "Data":heroItem.GetUserData(),
+ "SkinID":hero.skinID,
+ "LV":heroLV,
+ "Data":userData,
+ "FightPower":hero.fightPower,
+ "AttrDict":{str(k):v for k, v in hero.heroBatAttrDict.items() if v > 0},
+ "SkillIDList":skillIDlist,
}
-
- heroCount += 1
- if heroCount >= ShareDefine.LineupObjMax:
- break
-
- if not heroDict:
- return {}
+ lineupInfo.update({"Hero":heroDict})
- # 主公属性
- lordAttrDict = PlayerControl.GetLordAttr(curPlayer)
-
- # 其他
-
- lineupInfo = {"PlayerID":playerID, "LordAttrDict":lordAttrDict, "Hero":heroDict}
return lineupInfo
-def GetNPCLineup(lineupID):
+def GetNPCLineupInfo(lineupID):
## 获取NPC阵容信息
# @param lineupID: 阵容ID
# @return: 阵容全部信息json字典,前端通用格式
@@ -611,10 +504,26 @@
npcID = getattr(ipyData, "GetPosNPCID%s" % posNum)()
if not npcID:
continue
+ npcData = NPCCommon.GetNPCDataPy(npcID)
+ if not npcData:
+ continue
+ batAttrDict = {ChConfig.AttrID_Atk:npcData.GetAtk(), ChConfig.AttrID_Def:npcData.GetDef(), ChConfig.AttrID_MaxHP:npcData.GetMaxHP(),
+ ChConfig.AttrID_FinalDamPer:npcData.GetFinalDamPer(), ChConfig.AttrID_FinalDamPerDef:npcData.GetFinalDamPerDef(),
+ ChConfig.AttrID_MissRate:npcData.GetMissRate(), ChConfig.AttrID_MissRateDef:npcData.GetMissRateDef(),
+ ChConfig.AttrID_SuperHitRate:npcData.GetSuperHitRate(), ChConfig.AttrID_SuperHitRateDef:npcData.GetSuperHitRateDef(),
+ ChConfig.AttrID_StunRate:npcData.GetStunRate(), ChConfig.AttrID_StunRateDef:npcData.GetStunRateDef(),
+ ChConfig.AttrID_ComboRate:npcData.GetComboRate(), ChConfig.AttrID_ComboRateDef:npcData.GetComboRateDef(),
+ ChConfig.AttrID_ParryRate:npcData.GetParryRate(), ChConfig.AttrID_ParryRateDef:npcData.GetParryRateDef(),
+ ChConfig.AttrID_SuckHPPer:npcData.GetSuckHPPer(), ChConfig.AttrID_SuckHPPerDef:npcData.GetSuckHPPerDef(),
+ }
+ batAttrDict.update(npcData.GetSpecAttrInfo())
+ skillIDList = [] + npcData.GetSkillIDList()
+ heroDict[str(posNum)] = {"NPCID":npcID,
+ "AttrDict":{str(k):v for k, v in batAttrDict.items() if v > 0},
+ "SkillIDList":skillIDList
+ }
- heroDict[str(posNum)] = {"NPCID":npcID}
-
- lineupInfo = {"Hero":heroDict}
+ lineupInfo = {"NPCLineupID":lineupID, "Hero":heroDict}
return lineupInfo
def SummonLineupObjs(batLineup, faction, num, lineupInfo, playerID=0):
@@ -624,115 +533,79 @@
@param lineupInfo: 阵容信息
@param playerID: 发起的玩家ID,系统场次为0
'''
-
- '''关于视野层级说明 sightLevel
- 玩家发起的战斗视野层级只能用玩家ID,才能达到只通知该玩家的效果
- 但是由于同个玩家可能同时存在多场战斗,如主线战斗 + 其他战斗,所以视野层级只能用作仅通知该玩家的作用,
- 不能用于处理NPC视野来遍历伤害对象等,因为不同战场的NPC视野层级可能相同,对于同场战斗NPC的遍历处理只能用 turnFight 管理遍历
- 鉴于视野层级仅用于通知的作用,故系统场次理论上可以只用一个视野层级,但是为了减少不必要的问题,系统场次的视野层级还是尽量区分开来
- 这里暂时用时间戳的后4位来做短时间内的理论上唯一视野层级
- '''
GameWorld.DebugLog("SummonLineupObjs faction:%s,num:%s,lineupInfo=%s" % (faction, num, lineupInfo), playerID)
if playerID:
curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
if not curPlayer:
return
- posX, posY = curPlayer.GetPosX(), curPlayer.GetPosY()
- sightLevel = playerID
- # 开发过程中可以先开启视野层级及视野,方便检查战斗相关是否有遗漏
- if curPlayer.GetSightLevel() != sightLevel:
- PlayerControl.SetPlayerSightLevel(curPlayer, sightLevel)
- sight = ChConfig.Def_PlayerSight_Default * 5
- if curPlayer.GetSight() != sight:
- PlayerControl.SetSight(curPlayer, sight)
- else:
- gameMap = GameWorld.GetMap()
- posX, posY = gameMap.GetRebornMapX(), gameMap.GetRebornMapY() # 系统战斗默认取当前地图的复活点,需要优化
- sightLevel = 2000000000 + int(time.time()) % 10000
-
- GameWorld.DebugLog("sightLevel=%s,pos=(%s,%s)" % (sightLevel, posX, posY), playerID)
-
+ tfGUID = batLineup.turnFight.guid
lineupPlayerID = lineupInfo.get("PlayerID", 0) # 阵容所属玩家ID
heroDict = lineupInfo.get("Hero", {})
- tick = GameWorld.GetGameWorld().GetTick()
+ batObjMgr = BattleObj.GetBatObjMgr()
initXP = IpyGameDataPY.GetFuncCfg("AngerXP", 1)
- baseAtkSkillIDList = IpyGameDataPY.GetFuncEvalCfg("ParryCfg", 3)
- tfMgr = GetTurnFightMgr()
- space = 3
+ atkBackSkillIDList = IpyGameDataPY.GetFuncEvalCfg("ParryCfg", 3)
for posNumKey, heroInfo in heroDict.items():
posNum = int(posNumKey)
- heroID, skinID = 0, 0
- baseAtkSkillID = 0 # 基础普攻ID
- skillIDList = []
+ npcID, heroID, skinID = 0, 0, 0
+ atkBackSkillID = 0 # 反击技能ID
+ fightPower = 0
+ skillIDList = [] # 战斗对象可能改变属性或技能,重新创建,防止误修改来源值
+ attrDict = {}
+ skillIDList += heroInfo.get("SkillIDList", [])
+ attrDict.update(heroInfo.get("AttrDict", {}))
+ objName = ""
if lineupPlayerID:
heroID = heroInfo.get("HeroID", 0)
skinID = heroInfo.get("SkinID", 0)
- npcID = FighterNPCID
+ lv = heroInfo.get("LV", 1)
+ fightPower = heroInfo.get("FightPower", 0)
heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
if not heroIpyData:
continue
- normalSkillID = heroIpyData.GetNormalSkillID()
- angerSkillID = heroIpyData.GetAngerSkillID()
- skillIDList += [normalSkillID, angerSkillID]
atkDistType = heroIpyData.GetAtkDistType()
+ objName = heroIpyData.GetName()
else:
npcID = heroInfo.get("NPCID", 0)
- npcDataEx = NPCCommon.GetNPCDataEx(npcID)
+ npcDataEx = NPCCommon.GetNPCDataPy(npcID)
if not npcDataEx:
continue
- skillIDList += npcDataEx.GetSkillIDList()
+ objName = npcDataEx.GetNPCName()
atkDistType = npcDataEx.GetAtkDistType()
+ lv = npcDataEx.GetLV()
- if not npcID:
- continue
-
- npcData = GameWorld.GetGameData().FindNPCDataByID(npcID)
- if not npcData:
- continue
- curSummon = GameWorld.GetNPCManager().AddPlayerSummonNPC()
- if not curSummon:
- continue
- objID = curSummon.GetID()
- batLineup.npcPosDict[posNum] = curSummon
- batLineup.npcObjIDDict[objID] = curSummon
- tfMgr.setNPCGUID(objID, batLineup.getGUID())
-
- curSummon.SetNPCTypeID(npcID)
- curSummon.SetBornTime(tick)
- curSummon.SetAIType(0)
- curSummon.SetSightLevel(sightLevel)
- curSummon.SetIsNeedProcess(False)
- curSummon.SetCanAttack(True)
- 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)
+ batObj = batObjMgr.addBatObj()
+ if not batObj:
+ break
+ objID = batObj.GetID()
+ batObj.SetTFGUID(tfGUID)
+ batObj.SetName(objName)
+ batObj.SetFaction(faction)
+ batObj.SetLineupPos(posNum, num)
+ batObj.SetFightPower(fightPower)
+ batObj.SetLV(lv)
+ if npcID:
+ batObj.SetNPCID(npcID)
+ elif lineupPlayerID:
+ batObj.SetOwnerHero(lineupPlayerID, heroID, skinID)
+ batObj.InitBatAttr({int(k):v for k, v in attrDict.items()}, initXP)
if atkDistType == ChConfig.AtkDistType_Short:
- baseAtkSkillID = baseAtkSkillIDList[0] if len(baseAtkSkillIDList) > 0 else 0
+ atkBackSkillID = atkBackSkillIDList[0] if len(atkBackSkillIDList) > 0 else 0
elif atkDistType == ChConfig.AtkDistType_Long:
- baseAtkSkillID = baseAtkSkillIDList[1] if len(baseAtkSkillIDList) > 1 else 0
+ atkBackSkillID = atkBackSkillIDList[1] if len(atkBackSkillIDList) > 1 else 0
+ if atkBackSkillID:
+ skillIDList.append(atkBackSkillID)
+ skillManager = batObj.GetSkillManager()
+ skillManager.SkillReset()
+ for skillID in skillIDList:
+ skillManager.LearnSkillByID(skillID)
- skillManager = curSummon.GetSkillManager()
- #有指定的技能,重新学习
- if skillIDList:
- 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("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)
+ batLineup.posObjIDDict[posNum] = objID
+ GameWorld.DebugLog("AddBatObj ID:%s,faction:%s,num=%s,posNum=%s,skill=%s,atk=%s,def=%s,hp=%s"
+ % (objID, faction, num, posNum, skillIDList, batObj.GetAtk(), batObj.GetDef(), batObj.GetHP()))
return
@@ -841,7 +714,7 @@
teamNum = 1
lineupID = waveLineupList[teamNum - 1] # NPC阵容ID
- lineupMainInfo = GetPlayerLineup(curPlayer, ShareDefine.Lineup_Main)
+ lineupMainInfo = GetPlayerLineupInfo(curPlayer, ShareDefine.Lineup_Main)
if not lineupMainInfo:
GameWorld.DebugLog("没有设置主阵容!", playerID)
return
@@ -862,8 +735,8 @@
turnFight = mainFightMgr.turnFight
turnFight.setTurn(mapID, funcLineID, turnMax, False, {"teamNum":teamNum, "teamMax":teamMax})
- turnFight.setFactionLineup(Def_FactionA, {1:lineupMainInfo}, True)
- turnFight.setFactionLineup(Def_FactionB, {1:GetNPCLineup(lineupID)})
+ turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:lineupMainInfo}, True)
+ turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)})
turnFight.sortActionQueue()
turnFight.syncInit()
return
@@ -915,7 +788,7 @@
wave = waveMax = 1 # 关卡boss固定只有一波
- lineupMainInfo = GetPlayerLineup(curPlayer, ShareDefine.Lineup_Main)
+ lineupMainInfo = GetPlayerLineupInfo(curPlayer, ShareDefine.Lineup_Main)
if not lineupMainInfo:
GameWorld.DebugLog("没有设置主阵容!", playerID)
return
@@ -936,8 +809,8 @@
turnFight = mainFightMgr.turnFight
turnFight.setTurn(mapID, funcLineID, turnMax, False, {"teamNum":teamNum, "teamMax":teamMax})
- turnFight.setFactionLineup(Def_FactionA, {1:lineupMainInfo}, True)
- turnFight.setFactionLineup(Def_FactionB, {1:GetNPCLineup(lineupID)})
+ turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:lineupMainInfo}, True)
+ turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)})
turnFight.sortActionQueue()
turnFight.syncInit()
@@ -965,7 +838,7 @@
mainFightMgr.nextTeam = False
turnFight.resetTurn({"teamNum":teamNum})
# 切换小队时,玩家阵容不需要处理,保留状态
- turnFight.setFactionLineup(Def_FactionB, {1:GetNPCLineup(lineupID)})
+ turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)})
turnFight.sortActionQueue()
turnFight.syncInit()
@@ -993,6 +866,7 @@
doMax = (PosNumMax + 2) * len(turnFight.actionSortList) # 防止死循环,做最大循环次数限制 = (最大位置数 + 主公、红颜位置)*行动阵容数
overLineupList = [] # 本回合已经结束行动的阵容列表 [(faction, num), ...], 所有阵容全部结束代表本回合结束
+ batObjMgr = BattleObj.GetBatObjMgr()
turnNum = turnFight.turnNum
GameWorld.DebugLog("turnNum=%s,doMax=%s,actionIndex=%s,%s" % (turnNum, doMax, turnFight.actionIndex, turnFight.actionSortList))
while doCnt < doMax and len(overLineupList) < len(turnFight.actionSortList):
@@ -1011,8 +885,9 @@
batFaction = turnFight.getBatFaction(faction)
batLineup = batFaction.getBatlineup(num)
batLineup.actionNum = ActionNumStart
- for curNPC in batLineup.npcPosDict.values():
- TurnFightObjPerTurnStart(curNPC, None, turnNum, tick)
+ for objID in batLineup.posObjIDDict.values():
+ batObj = batObjMgr.getBatObj(objID)
+ TurnFightObjPerTurnStart(turnFight, batObj, turnNum)
if turnFight.actionIndex >= len(turnFight.actionSortList):
turnFight.actionIndex = 0
@@ -1021,14 +896,14 @@
faction, num = turnFight.actionSortList[turnFight.actionIndex]
batFaction = turnFight.getBatFaction(faction)
batLineup = batFaction.getBatlineup(num)
- if batLineup.actionNum > max(batLineup.npcPosDict):
+ if batLineup.actionNum > max(batLineup.posObjIDDict):
if (faction, num) not in overLineupList:
overLineupList.append((faction, num))
turnFight.actionIndex += 1
continue
- if faction == Def_FactionA:
+ if faction == ChConfig.Def_FactionA:
if not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, fightPoint):
GameWorld.DebugLog("战锤不足!")
return
@@ -1046,31 +921,21 @@
elif batLineup.actionNum > 0:
for posNum in range(batLineup.actionNum, PosNumMax + 1):
batLineup.actionNum = posNum
- if posNum not in batLineup.npcPosDict:
+ if posNum not in batLineup.posObjIDDict:
continue
- curNPC = batLineup.npcPosDict[posNum]
- if not curNPC or GameObj.GetHP(curNPC) <= 0:
- continue
- objType = curNPC.GetGameObjType()
- objID = curNPC.GetID()
- turnFight.syncObjAction(turnNum, objType, objID)
-
- objName = GetObjName(curNPC)
- curHP = GameObj.GetHP(curNPC)
-
- GameWorld.DebugLog("★回合%s %s 行动 : curHP=%s" % (turnNum, objName, curHP))
- if not DoAttack(curNPC, None, tick):
- GameWorld.DebugLog(" 攻击失败")
+ objID = batLineup.posObjIDDict[posNum]
+ batObj = batObjMgr.getBatObj(objID)
+ if not OnObjAction(turnFight, batObj):
continue
- if faction == Def_FactionA:
+ if faction == ChConfig.Def_FactionA:
playerHeroAtk = True
break
turnFight.actionIndex += 1
batLineup.actionNum += 1
- if batLineup.actionNum > max(batLineup.npcPosDict):
+ if batLineup.actionNum > max(batLineup.posObjIDDict):
GameWorld.DebugLog("该阵容本回合已经全部行动完了: turnNum=%s,faction=%s,num=%s,actionNum=%s" % (turnFight.turnNum, faction, num, batLineup.actionNum))
if (faction, num) not in overLineupList:
overLineupList.append((faction, num))
@@ -1097,7 +962,7 @@
for faction, num in turnFight.actionSortList:
batFaction = turnFight.getBatFaction(faction)
batLineup = batFaction.getBatlineup(num)
- for curNPC in batLineup.npcPosDict.values():
+ for objID in batLineup.posObjIDDict.values():
pass
if turnFight.checkOverByKilled():
@@ -1116,6 +981,7 @@
curPlayer = turnFight.curPlayer
turnMax = turnFight.turnMax
EntryLogic(turnFight)
+ batObjMgr = BattleObj.GetBatObjMgr()
for turnNum in range(1, turnMax + 1):
turnFight.turnNum = turnNum
GameWorld.DebugLog("【----- 回合制战斗轮次: %s -----】" % turnNum)
@@ -1128,8 +994,9 @@
batFaction = turnFight.getBatFaction(faction)
batLineup = batFaction.getBatlineup(num)
batLineup.actionNum = 1
- for curNPC in batLineup.npcPosDict.values():
- TurnFightObjPerTurnStart(curNPC, None, turnNum, tick)
+ for objID in batLineup.posObjIDDict.values():
+ batObj = batObjMgr.getBatObj(objID)
+ TurnFightObjPerTurnStart(turnFight, batObj, turnNum)
# 主公
for faction, num in turnFight.actionSortList:
@@ -1156,20 +1023,11 @@
batLineup = batFaction.getBatlineup(num)
for posNum in range(batLineup.actionNum, PosNumMax + 1):
batLineup.actionNum = posNum + 1
- if posNum not in batLineup.npcPosDict:
+ if posNum not in batLineup.posObjIDDict:
continue
- curNPC = batLineup.npcPosDict[posNum]
- if not curNPC or GameObj.GetHP(curNPC) <= 0:
- continue
- objType = curNPC.GetGameObjType()
- objID = curNPC.GetID()
- turnFight.syncObjAction(turnNum, objType, objID)
-
- objName = GetObjName(curNPC)
- curHP = GameObj.GetHP(curNPC)
-
- GameWorld.DebugLog("★回合%s %s 行动 : curHP=%s" % (turnNum, objName, curHP))
- if not DoAttack(curNPC, None, tick):
+ objID = batLineup.posObjIDDict[posNum]
+ batObj = batObjMgr.getBatObj(objID)
+ if not OnObjAction(turnFight, batObj):
continue
break
@@ -1184,7 +1042,7 @@
GameWorld.DebugLog("回合结束逻辑: turnNum=%s,faction=%s, num=%s" % (turnNum, faction, num))
batFaction = turnFight.getBatFaction(faction)
batLineup = batFaction.getBatlineup(num)
- for curNPC in batLineup.npcPosDict.values():
+ for objID in batLineup.posObjIDDict.values():
pass
if turnFight.checkOverByKilled():
@@ -1212,14 +1070,15 @@
#funcLineID = clientData.FuncLineID
return
-def GetObjName(gameObj):
- objName = gameObj.GetName()
- faction = GameObj.GetFaction(gameObj)
- posInfo = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo)
- heroID = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_HeroID)
+def GetObjName(batObj):
+ faction = batObj.faction
+ num = batObj.lineupNum
+ posNum = batObj.posNum
+ heroID = batObj.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)
+ heroID = batObj.npcID
+ objName = GameWorld.CodeToGbk(batObj.GetName())
+ return "%s%s-%s [%s-%s] %s" % ("A" if faction == ChConfig.Def_FactionA else "B", num, posNum, batObj.GetID(), heroID, objName)
def EntryLogic(turnFight):
## 执行进场逻辑
@@ -1230,11 +1089,32 @@
turnFight.enterLogic = True
return
-def TurnFightObjPerTurnStart(gameObj, tagObj, turnNum, tick):
+def TurnFightObjPerTurnStart(turnFight, batObj, turnNum):
## 回合制战斗实例 - 每回合开始时处理
- if not gameObj:
+ if not batObj:
return
+ if batObj.GetHP() <= 0:
+ return
+
+ curID = batObj.GetID()
+ buffMgr = batObj.GetBuffManager()
+ GameWorld.DebugLog("更新buff: curID=%s,buffCount=%s" % (curID, buffMgr.GetBuffCount()))
+ for index in range(buffMgr.GetBuffCount()):
+ buff = buffMgr.GetBuffByIndex(index)
+ curRemainTime = buff.GetRemainTime()
+ if not curRemainTime:
+ # 永久buff不处理
+ continue
+ buffID = buff.GetBuffID()
+ updRemainTime = curRemainTime - 1
+ GameWorld.DebugLog(" 更新buff剩余回合数: buffID=%s,updRemainTime=%s" % (buffID, updRemainTime))
+ if updRemainTime > 0:
+ buff.SetRemainTime(curRemainTime - 1)
+ TurnBuff.SyncBuffRefresh(turnFight, batObj, buff)
+ else:
+ TurnBuff.SyncBuffDel(turnFight, batObj, buffID)
+
# SetTimeline(gameObj, turnNum, 0)
# # 重置连击、反击数
# gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnComboNum, 0)
@@ -1272,190 +1152,201 @@
def AddTurnObjCureHP(curObj, srcObj, addValue, cureHP, skillID=0):
## 回合对象添加治疗值
- if not curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
+ # @param curObj: 获得治疗的对象
+ # @param srcObj: 来自谁的治疗
+ # @param addValue: 治疗值
+ # @param cureHP: 实际回血量
+ if not srcObj:
return
-
- curFaction = GameObj.GetFaction(curObj)
- if not srcObj or curFaction != GameObj.GetFaction(srcObj):
- # 同阵营的治疗才统计
- return
-
curID = curObj.GetID()
srcID = srcObj.GetID()
- turnFight = GetTurnFightMgr().getNPCTurnFight(curID)
- if not turnFight:
- return
-
- curBatFaction = turnFight.getBatFaction(curFaction)
- for num in curBatFaction.lineupDict.keys():
- batLineup = curBatFaction.getBatlineup(num)
- updStatValue = batLineup.statCureValue(srcID, cureHP)
- if updStatValue == None:
- continue
- GameWorld.DebugLog(" 统计治疗: curTD=%s,srcID=%s,skillID=%s,addValue=%s,cureHP=%s,updStatValue=%s"
- % (curID, srcID, skillID, addValue, cureHP, updStatValue))
- break
-
+ updStatValue = srcObj.StatCureValue(cureHP)
+ GameWorld.DebugLog(" 统计治疗: curID=%s,srcID=%s,skillID=%s,addValue=%s,cureHP=%s,updStatValue=%s"
+ % (curID, srcID, skillID, addValue, cureHP, updStatValue))
+
return
-def AddTurnObjHurtValue(curObj, tagObj, hurtType, hurtValue, lostHP, curSkill=None):
+def AddTurnObjHurtValue(curBatObj, tagBatObj, hurtValue, lostHP, curSkill=None, isBounce=False):
## 回合对象添加伤害值
- if not curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
- return
- curID = curObj.GetID()
- tagID = tagObj.GetID()
+ # @param isBounce: 是否反弹伤害
+ curID = curBatObj.GetID()
+ tagID = tagBatObj.GetID()
skillID = curSkill.GetSkillID() if curSkill else 0
- turnFight = GetTurnFightMgr().getNPCTurnFight(curID)
- if not turnFight:
- return
-
if curID != tagID:
- curBatFaction = turnFight.getBatFaction(GameObj.GetFaction(curObj))
- for num in curBatFaction.lineupDict.keys():
- batLineup = curBatFaction.getBatlineup(num)
- updStatValue = batLineup.statHurtValue(curID, lostHP)
- if updStatValue == None:
- continue
- GameWorld.DebugLog(" 统计伤血: curTD=%s,tagID=%s,skillID=%s,hurtType=%s,hurtValue=%s,lostHP=%s,updStatValue=%s,tagHP=%s"
- % (curID, tagID, skillID, hurtType, hurtValue, lostHP, updStatValue, GameObj.GetHP(tagObj)))
- break
+ updStatValue = curBatObj.StatHurtValue(hurtValue)
+ GameWorld.DebugLog(" 统计伤血: curID=%s,tagID=%s,skillID=%s,hurtValue=%s,lostHP=%s,updStatValue=%s,tagHP=%s,isBounce=%s"
+ % (curID, tagID, skillID, hurtValue, lostHP, updStatValue, tagBatObj.GetHP(), isBounce))
- tagBatFaction = turnFight.getBatFaction(GameObj.GetFaction(tagObj))
- for num in tagBatFaction.lineupDict.keys():
- batLineup = tagBatFaction.getBatlineup(num)
- updStatValue = batLineup.statDefValue(tagID, lostHP)
- if updStatValue == None:
- continue
- GameWorld.DebugLog(" 统计承伤: curTD=%s,tagID=%s,skillID=%s,hurtType=%s,hurtValue=%s,lostHP=%s,updStatValue=%s,curHP=%s"
- % (tagID, curID, skillID, hurtType, hurtValue, lostHP, updStatValue, GameObj.GetHP(tagObj)))
- break
-
+ if tagBatObj:
+ updStatValue = tagBatObj.StatDefValue(lostHP)
+ GameWorld.DebugLog(" 统计承伤: curID=%s,tagID=%s,skillID=%s,hurtValue=%s,lostHP=%s,updStatValue=%s,curHP=%s,isBounce=%s"
+ % (tagID, curID, skillID, hurtValue, lostHP, updStatValue, tagBatObj.GetHP(), isBounce))
+
else:
# 如换血类技能,自残的伤害不算输出
- GameWorld.DebugLog(" 自残: curTD=%s,tagID=%s,skillID=%s,hurtType=%s,hurtValue=%s,lostHP=%s,curHP=%s"
- % (curID, tagID, skillID, hurtType, hurtValue, lostHP, GameObj.GetHP(curObj)))
-
- if lostHP > 0 and curID != tagID:
- addXP = IpyGameDataPY.GetFuncCfg("AngerXP", 4)
- AddTurnFightXP(tagObj, addXP, "skillID:%s" % skillID)
+ GameWorld.DebugLog(" 自残: curID=%s,tagID=%s,skillID=%s,hurtValue=%s,lostHP=%s,curHP=%s"
+ % (curID, tagID, skillID, hurtValue, lostHP, curBatObj.GetHP()))
return
-def AddTurnFightXP(gameObj, addXP, reason=""):
- ## 回合战斗增加XP
- if addXP <= 0 or not addXP:
- #GameWorld.DebugLog(" 没有增加XP! curID=%s" % (gameObj.GetID()))
+def OnObjAction(turnFight, curBatObj):
+ ## 战斗单位行动
+ if not curBatObj:
return
- posNum = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo) % 10
- if posNum <= 0:
- #非主战单位不加
+
+ curHP = curBatObj.GetHP()
+ objID = curBatObj.GetID()
+ if curHP <= 0:
return
- curXP = GameObj.GetXP(gameObj)
- updXP = curXP + addXP
- GameObj.SetXP(gameObj, updXP)
- GameWorld.DebugLog(" 更新XP: curID=%s,curXP=%s,addXP=%s,updXP=%s,reason=%s" % (gameObj.GetID(), curXP, addXP, updXP, reason))
+
+ turnNum = turnFight.turnNum
+ objName = GetObjName(curBatObj)
+
+ # 是否可行动状态判断
+ canAction = True
+
+ if not canAction:
+ GameWorld.DebugLog("★回合%s %s 当前状态不可行动!" % (turnNum, objName))
+ return
+
+ GameWorld.DebugLog("★回合%s %s 行动 : curHP=%s" % (turnNum, objName, curHP))
+ turnFight.syncObjAction(turnNum, objID)
+
+ curXP = curBatObj.GetXP()
+ xpMax = IpyGameDataPY.GetFuncCfg("AngerXP", 2)
+ skillManager = curBatObj.GetSkillManager()
+ useSkillList = []
+ #GameWorld.DebugLog('skillCount=%s' % skillManager.GetSkillCount(), npcID)
+ for index in range(0, skillManager.GetSkillCount()):
+ useSkill = skillManager.GetSkillByIndex(index)
+ if not useSkill:
+ continue
+ if useSkill.GetFuncType() in [ChConfig.Def_SkillFuncType_AtkbackSkill]:
+ #基础普攻不能主动释放,目前仅用于反击
+ continue
+ #被动技能无法使用
+ if SkillCommon.isPassiveSkill(useSkill):
+ continue
+ #还在冷却时间内无法释放
+ if useSkill.GetRemainTime():
+ continue
+ skillID = useSkill.GetSkillID()
+ # 常规攻击优先xp
+ if SkillCommon.isAngerSkill(useSkill):
+ if curXP < xpMax:
+ continue
+ useCnt = -1 # xp技能优先释放
+ else:
+ useCnt = curBatObj.GetSkillUseCnt(skillID)
+ useSkillList.append([useCnt, skillID, useSkill])
+
+ useSkillList.sort() # 按使用次数优先升序排,使用次数低的优先判断使用
+ #GameWorld.DebugLog(' 技能使用顺序 = useSkillList%s' % str(useSkillList), npcID)
+
+ for useInfo in useSkillList:
+ useSkill = useInfo[-1]
+ if TurnSkill.OnUseSkill(turnFight, curBatObj, useSkill):
+ return True
+
return
-def DoAttack(curNPC, tagNPC, tick, turnBattleType=ChConfig.TurnBattleType_Normal, useSkill=None):
- curID = curNPC.GetID()
- npcID = curNPC.GetNPCID()
- objName = GetObjName(curNPC)
- GameWorld.DebugLog(" ● %s DoAttack: curID=%s,,turnBattleType=%s" % (objName, curID, turnBattleType))
-
- atkOK = False
- tagObj = tagNPC
- curNPC.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, turnBattleType)
-
- if turnBattleType == ChConfig.TurnBattleType_AtkBack:
- if not tagObj:
- return
- 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
- atkOK = SkillShell.DoLogic_UseSkill(curNPC, tagObj, useSkill, tick)
- else:
- curXP = GameObj.GetXP(curNPC)
- xpMax = IpyGameDataPY.GetFuncCfg("AngerXP", 2)
- skillManager = curNPC.GetSkillManager()
- useSkillList = []
- #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 SkillCommon.RefreshSkillRemainTime(useSkill, tick) != 0:
- continue
- skillTypeID = useSkill.GetSkillTypeID()
- # 常规攻击优先xp
- if SkillCommon.isAngerSkill(useSkill) and turnBattleType == ChConfig.TurnBattleType_Normal:
- if curXP < xpMax:
- continue
- useCnt = -1 # xp技能优先释放
- else:
- useCnt = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SkillUseCnt % skillTypeID) # 该技能已使用次数
- useSkillList.append([useCnt, index, skillTypeID, useSkill])
-
- useSkillList.sort() # 按使用次数优先升序排,使用次数低的优先判断使用
- #GameWorld.DebugLog(' 技能使用顺序 = useSkillList%s' % str(useSkillList), npcID)
-
- for useInfo in useSkillList:
- useSkill = useInfo[-1]
- #skillID = useSkill.GetSkillID()
- atkOK, tagObj = DoNPCUseSkill(curNPC, useSkill, tick)
- if atkOK:
- break
-
- curNPC.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, 0) # 无论攻击成功与否都重置战斗类型
-
- tagID = 0
- tagHP = 0
- if tagObj:
- tagID = tagObj.GetID()
- tagHP = GameObj.GetHP(tagObj)
- GameWorld.DebugLog(' atkOK=%s,tagID=%s,tagHP=%s' % (atkOK, tagID, tagHP), npcID)
- if not atkOK:
- return
-
- if not tagObj:
- return
-
- if GameObj.GetFaction(curNPC) == GameObj.GetFaction(tagObj):
- # 同阵营直接返回,不处理连击、反击
- return True
-
- curHP = GameObj.GetHP(curNPC)
- tagHP = GameObj.GetHP(tagObj)
- tagID = tagObj.GetID()
- GameWorld.DebugLog(" curID-HP=(%s-%s),tagID-HP=(%s-%s)" % (curID, curHP, tagID, tagHP))
- if tagHP <= 0 or curHP <= 0:
- return True
-
- # 反击,反击可打断连击,所以优先判断
- if CanAtkBack(curNPC, tagObj):
- DoAttack(tagObj, curNPC, tick, ChConfig.TurnBattleType_AtkBack)
- return True
-
- # 连击
- if CanCombo(curNPC, tagObj):
- DoAttack(curNPC, tagObj, tick, ChConfig.TurnBattleType_Combo, useSkill)
-
+def DoAttack(curBatObj, tagBatObj, tick, turnBattleType=ChConfig.TurnBattleType_Normal, useSkill=None):
+# curID = curBatObj.GetID()
+# npcID = curBatObj.GetNPCID()
+# objName = GetObjName(curBatObj)
+# GameWorld.DebugLog(" ● %s DoAttack: curID=%s,,turnBattleType=%s" % (objName, curID, turnBattleType))
+#
+# atkOK = False
+# curBatObj.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, turnBattleType)
+#
+# if turnBattleType == ChConfig.TurnBattleType_AtkBack:
+# if not tagBatObj:
+# return
+# skillManager = curBatObj.GetSkillManager()
+# for index in range(0, skillManager.GetSkillCount()):
+# skill = skillManager.GetSkillByIndex(index)
+# if not skill:
+# continue
+# if skill.GetFuncType() == ChConfig.Def_SkillFuncType_AtkbackSkill:
+# useSkill = skill
+# break
+# atkOK = SkillShell.DoLogic_UseSkill(curBatObj, tagBatObj, useSkill, tick)
+# elif turnBattleType == ChConfig.TurnBattleType_Combo:
+# if not tagBatObj:
+# return
+# atkOK = SkillShell.DoLogic_UseSkill(curBatObj, tagBatObj, useSkill, tick)
+# else:
+# curXP = GameObj.GetXP(curBatObj)
+# xpMax = IpyGameDataPY.GetFuncCfg("AngerXP", 2)
+# skillManager = curBatObj.GetSkillManager()
+# useSkillList = []
+# #GameWorld.DebugLog('skillCount=%s' % skillManager.GetSkillCount(), npcID)
+# for index in range(0, skillManager.GetSkillCount()):
+# useSkill = skillManager.GetSkillByIndex(index)
+# if not useSkill:
+# continue
+# if useSkill.GetFuncType() in [ChConfig.Def_SkillFuncType_AtkbackSkill]:
+# #基础普攻不能主动释放,目前仅用于反击
+# continue
+# #被动技能无法使用
+# if SkillCommon.isPassiveSkill(useSkill):
+# continue
+# #还在冷却时间内无法释放
+# if useSkill.GetRemainTime():
+# continue
+# skillID = useSkill.GetSkillID()
+# # 常规攻击优先xp
+# if SkillCommon.isAngerSkill(useSkill) and turnBattleType == ChConfig.TurnBattleType_Normal:
+# if curXP < xpMax:
+# continue
+# useCnt = -1 # xp技能优先释放
+# else:
+# useCnt = curBatObj.GetDictByKey(ChConfig.Def_NPC_Dict_SkillUseCnt % skillID) # 该技能已使用次数
+# useSkillList.append([useCnt, index, skillID, useSkill])
+#
+# useSkillList.sort() # 按使用次数优先升序排,使用次数低的优先判断使用
+# #GameWorld.DebugLog(' 技能使用顺序 = useSkillList%s' % str(useSkillList), npcID)
+#
+# for useInfo in useSkillList:
+# useSkill = useInfo[-1]
+# #skillID = useSkill.GetSkillID()
+# atkOK, tagBatObj = OnUseSkill(curBatObj, useSkill, tick)
+# if atkOK:
+# break
+#
+# curBatObj.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, 0) # 无论攻击成功与否都重置战斗类型
+#
+# tagID = 0
+# tagHP = 0
+# if tagObj:
+# tagID = tagObj.GetID()
+# tagHP = GameObj.GetHP(tagObj)
+# GameWorld.DebugLog(' atkOK=%s,tagID=%s,tagHP=%s' % (atkOK, tagID, tagHP), npcID)
+# if not atkOK:
+# return
+#
+# if not tagObj:
+# return
+#
+# if GameObj.GetFaction(curNPC) == GameObj.GetFaction(tagObj):
+# # 同阵营直接返回,不处理连击、反击
+# return True
+#
+# curHP = GameObj.GetHP(curNPC)
+# tagHP = GameObj.GetHP(tagObj)
+# tagID = tagObj.GetID()
+# GameWorld.DebugLog(" curID-HP=(%s-%s),tagID-HP=(%s-%s)" % (curID, curHP, tagID, tagHP))
+# if tagHP <= 0 or curHP <= 0:
+# return True
+#
+# # 反击,反击可打断连击,所以优先判断
+# if CanAtkBack(curNPC, tagObj):
+# DoAttack(tagObj, curNPC, tick, ChConfig.TurnBattleType_AtkBack)
+# return True
+#
+# # 连击
+# if CanCombo(curNPC, tagObj):
+# DoAttack(curNPC, tagObj, tick, ChConfig.TurnBattleType_Combo, useSkill)
+#
return True
def CanAtkBack(atkObj, defObj):
@@ -1512,224 +1403,58 @@
% (atkObj.GetID(), comboNum, comboRate, atkComboRate, defComboReduce))
return True
-def DoNPCUseSkill(curNPC, useSkill, tick):
- '''NPC使用技能
- @return: 是否成功, tagObj
- '''
- if not useSkill or useSkill.GetSkillTypeID() == 0:
- return False, None
-
- #检查是否几率触发
- rate = useSkill.GetHappenRate()
- if rate != ChConfig.Def_MaxRateValue and not GameWorld.CanHappen(rate, ChConfig.Def_MaxRateValue):
- #GameWorld.Log('检查是否几率触发 = %s失败 = %s'%(rate, useSkill.GetSkillName()))
- return False, None
-
- tagObj = None
- skillTag = SkillShell.GetSkillAffectTag(useSkill)
- skillAim = SkillShell.GetSkillFireAim(useSkill)
-
- # 注: 多V多的情况友好目标仅针对本阵容、敌对目标可针对任意敌对阵容
-
- #---对自己释放,或者无目标技能---
- if skillTag in ChConfig.Def_ST_CanNPCUseSkill or skillAim == ChConfig.Def_UseSkillAim_None:
- #释放自身类技能
- tagObj = curNPC
- isOK = SkillShell.DoLogic_UseSkill(curNPC, tagObj, useSkill, tick)
- return isOK, tagObj
-
- # 召唤兽对主人释放技能
- elif skillTag == ChConfig.Def_UseSkillTag_SummonMaster:
- if not NPCCommon.IsSummonNPC(curNPC):
- GameWorld.ErrLog("该NPC非召唤兽,无法获得主人释放技能")
- return False, None
-
- curSummonOwner = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curNPC)
- if curSummonOwner == None:
- curSummonOwner = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotNPC, curNPC)
-
- if curSummonOwner == None:
- GameWorld.ErrLog("召唤兽(%s)对主人释放技能,找不到主人" % curNPC.GetNPCID())
- return False, None
-
- tagObj = curSummonOwner
-
- # 友好死亡目标,一般是复活技能
- elif skillTag == ChConfig.Def_UseSkillTag_FriendDeath:
- deathList = GetFriendDeathList(curNPC)
- if not deathList:
- return False, None
- tagObj = random.choice(deathList) # 随机选一个
-
- # 友好目标
- elif skillTag in ChConfig.Def_ST_CanNPCUseSkillFriend:
- friendList = GetFriendObjList(curNPC)
- if not friendList:
- return False, None
- tagObj = random.choice(friendList) # 随机选一个,可扩展其他选择规则
-
- # 敌方目标
- else:
- tagObj = GetEnemyObj(curNPC)
-
- if not tagObj:
- return False, None
-
- GameWorld.DebugLog(" 技能释放: skillID=%s,atkID=%s,def=%s,HP:%s/%s"
- % (useSkill.GetSkillID(), curNPC.GetID(), GetObjName(tagObj), GameObj.GetHP(tagObj), GameObj.GetMaxHP(tagObj)))
- isOK = SkillShell.DoLogic_UseSkill(curNPC, tagObj, useSkill, tick)
- return isOK, tagObj
+#def GetEnemyObj(curNPC, ruleType=0):
+# ## 获取一个敌对单位,针对所有敌对阵容主战单位,优先选择对位阵容单位,仅限活着的单位
+# # @param ruleType: 选择规则,默认0任意,1-最低血量;2-最高血量
+# objID = curNPC.GetID()
+# faction = GameObj.GetFaction(curNPC)
+# posInfo = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo)
+# num = posInfo / 100 # 阵容编号
+# posNum = posInfo % 100 # 所在阵容站位
+# turnFight = GetTurnFightMgr().getTurnFight(curNPC.GetTFGUID())
+# if not turnFight:
+# return
+#
+# tagBatFaction = turnFight.getBatFaction(Def_FactionB if faction == Def_FactionA else Def_FactionA)
+#
+# tagLineupNumList = [num] # 目标阵容选择顺序,优先对位阵容,再其他阵容
+# if num in tagBatFaction.lineupDict:
+# tagLineupNumList = [num]
+# for tagNum in tagBatFaction.lineupDict.keys():
+# if tagNum not in tagLineupNumList:
+# tagLineupNumList.append(tagNum)
+#
+# batObjMgr = BattleObj.GetBatObjMgr()
+# for tagNum in tagLineupNumList:
+# tagLineup = tagBatFaction.getBatlineup(tagNum)
+# tagPosNumList = [posNum] # 优先对位位置,再其他位置按顺序遍历
+# pNumList = tagLineup.posObjIDDict.keys()
+# pNumList.sort()
+# for pNum in pNumList:
+# if pNum > 0 and pNum not in tagPosNumList:
+# tagPosNumList.append(pNum)
+# for pNum in tagPosNumList:
+# batObj = batObjMgr.getBatObj(objID)
+# if not batObj:
+# continue
+# if batObj.GetHP( )<= 0:
+# continue
+# return batObj
+# return
-def GetFriendDeathList(curNPC):
- ## 获取友方死亡单位,仅针对本阵容主战单位
- objID = curNPC.GetID()
- turnFight = GetTurnFightMgr().getNPCTurnFight(objID)
- if not turnFight:
- return []
- batFaction = turnFight.getBatFaction(GameObj.GetFaction(curNPC))
- num = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo) / 100
- batLineup = batFaction.getBatlineup(num)
- deathList = []
- for posNum, tagNPC in batLineup.npcPosDict.items():
- if posNum <= 0 or not tagNPC:
- continue
- if GameObj.GetHP(tagNPC) > 0:
- continue
- deathList.append(tagNPC)
-
- return deathList
-
-def GetFriendObjList(curNPC):
- ## 获取友方单位,仅针对本阵容主战单位
- objID = curNPC.GetID()
- turnFight = GetTurnFightMgr().getNPCTurnFight(objID)
- if not turnFight:
- return []
- batFaction = turnFight.getBatFaction(GameObj.GetFaction(curNPC))
- num = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo) / 100
- batLineup = batFaction.getBatlineup(num)
- friendList = []
- for posNum, tagNPC in batLineup.npcPosDict.items():
- if posNum <= 0 or not tagNPC:
- continue
- if GameObj.GetHP(tagNPC) <= 0:
- continue
- friendList.append(tagNPC)
- return friendList
-
-def GetEnemyObj(curNPC, ruleType=0):
- ## 获取一个敌对单位,针对所有敌对阵容主战单位,优先选择对位阵容单位,仅限活着的单位
- # @param ruleType: 选择规则,默认0任意,1-最低血量;2-最高血量
- objID = curNPC.GetID()
- faction = GameObj.GetFaction(curNPC)
- posInfo = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo)
- num = posInfo / 100 # 阵容编号
- posNum = posInfo % 100 # 所在阵容站位
- turnFight = GetTurnFightMgr().getNPCTurnFight(objID)
- if not turnFight:
- return
-
- tagBatFaction = turnFight.getBatFaction(Def_FactionB if faction == Def_FactionA else Def_FactionA)
-
- tagLineupNumList = [num] # 目标阵容选择顺序,优先对位阵容,再其他阵容
- if num in tagBatFaction.lineupDict:
- tagLineupNumList = [num]
- for tagNum in tagBatFaction.lineupDict.keys():
- if tagNum not in tagLineupNumList:
- tagLineupNumList.append(tagNum)
-
- for tagNum in tagLineupNumList:
- tagLineup = tagBatFaction.getBatlineup(tagNum)
- tagPosNumList = [posNum] # 优先对位位置,再其他位置按顺序遍历
- pNumList = tagLineup.npcPosDict.keys()
- pNumList.sort()
- for pNum in pNumList:
- if pNum > 0 and pNum not in tagPosNumList:
- tagPosNumList.append(pNum)
- for pNum in tagPosNumList:
- tagNPC = tagLineup.npcPosDict.get(pNum)
- if not tagNPC:
- continue
- if GameObj.GetHP(tagNPC) <= 0:
- continue
- return tagNPC
- return
-
-def SetTurnObjKilled(gameObj, killer=None):
- if not gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
- #GameWorld.DebugLog("非回合战斗主体被击杀: curID=%s" % gameObj.GetID())
- return
-
+def SetObjKilled(turnFight, gameObj, killer=None, useSkill=None):
objID = gameObj.GetID()
GameWorld.DebugLog(" %s 回合战斗主体被击杀: curID=%s" % (GetObjName(gameObj), objID))
- gameObj.SetCurAction(IPY_GameWorld.laNPCDie)
- if GameObj.GetHP(gameObj) != 0:
- GameObj.SetHP(gameObj, 0) # 回合制死亡仅设置为0,实例暂时不回收
- gameObj.SetVisible(False)
+ gameObj.SetHP(0)
+ killerObjID = killer.GetID() if killer else 0
+ skillID = useSkill.GetSkillID() if useSkill else 0
- turnFight = GetTurnFightMgr().getNPCTurnFight(objID)
- if not turnFight:
- return True
- clientPack = ChPyNetSendPack.tagMCTurnFightObjDead()
+ clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagMCTurnFightObjDead)
clientPack.ObjID = objID
- turnFight.addBatPack(clientPack)
-
- # 记录主动发起的玩家阵营击杀
- curPlayer = turnFight.curPlayer
- if killer and curPlayer and killer.GetDictByKey(ChConfig.Def_Obj_Dict_LineupPlayerID) == curPlayer.GetPlayerID():
- if objID not in turnFight.playerKillObjIDList:
- turnFight.playerKillObjIDList.append(objID)
- GameWorld.DebugLog("玩家单次击杀统计: %s" % turnFight.playerKillObjIDList)
-
+ clientPack.KillerObjID = killerObjID
+ clientPack.SkillID = skillID
+ turnFight.addBatPack(clientPack)
return True
-
-def OnTurnfightAttackSuccess(curObj, tagObj, curSkill):
- ## 回合战斗攻击成功额外处理,AttackResult之前,一般处理技能相关
- if curObj.GetGameObjType() != IPY_GameWorld.gotNPC:
- return
- if not curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
- return
-
- objID = curObj.GetID()
- turnFight = GetTurnFightMgr().getNPCTurnFight(objID)
- if not turnFight:
- return
-
- skillID = curSkill.GetSkillID() if curSkill else 0
- isXP = SkillCommon.isAngerSkill(curSkill)
- if isXP:
- GameObj.SetXP(curObj, 0)
- elif curSkill:
- if SkillCommon.isTurnNormalSkill(curSkill):
- addXP = IpyGameDataPY.GetFuncCfg("AngerXP", 3)
- AddTurnFightXP(curObj, addXP, "skillID:%s" % skillID)
-
- curPlayer = turnFight.curPlayer
- # 仅主动发起玩家阵容触发
- if curPlayer and curObj.GetDictByKey(ChConfig.Def_Obj_Dict_LineupPlayerID) == curPlayer.GetPlayerID():
- FBLogic.OnPlayerLineupAttackSuccess(curPlayer, curObj, tagObj, curSkill, turnFight.mapID, turnFight.funcLineID)
-
- return
-
-def OnTurnfightAttackResult(curObj, tagObj, curSkill):
- ## 回合战斗攻击结果额外处理,AttackResult 之后,一般处理击杀结算相关
- if curObj.GetGameObjType() != IPY_GameWorld.gotNPC:
- return
- if not curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
- return
-
- objID = curObj.GetID()
- turnFight = GetTurnFightMgr().getNPCTurnFight(objID)
- if not turnFight:
- return
-
- curPlayer = turnFight.curPlayer
- # 仅主动发起玩家阵容触发
- if curPlayer and curObj.GetDictByKey(ChConfig.Def_Obj_Dict_LineupPlayerID) == curPlayer.GetPlayerID():
- FBLogic.OnPlayerLineupAttackResult(curPlayer, curObj, tagObj, curSkill, turnFight.mapID, turnFight.funcLineID)
-
- turnFight.playerKillObjIDList = []
- return
def OnTurnAllOver(guid):
## 所有回合已经全部执行完毕
@@ -1743,10 +1468,10 @@
if turnFight.playerID:
# 玩家发起的,未击杀对方,算玩家输
- turnFight.winFaction = Def_FactionB
+ turnFight.winFaction = ChConfig.Def_FactionB
else:
# 系统场次,按一定规则来,这里先随机
- turnFight.winFaction = random.choice([Def_FactionA, Def_FactionB])
+ turnFight.winFaction = random.choice([ChConfig.Def_FactionA, ChConfig.Def_FactionB])
DoTurnFightOver(guid)
return
@@ -1763,6 +1488,7 @@
GameWorld.DebugLog("--- 战斗结束处理 --- %s, winFaction=%s, costTime=%ss" % (guid, winFaction, turnFight.costTime))
# 统计明细
+ batObjMgr = BattleObj.GetBatObjMgr()
statInfo = {}
for faction in turnFight.factionDict.keys():
if str(faction) not in statInfo:
@@ -1774,26 +1500,26 @@
facStatInfo[str(num)] = {}
lineupStatInfo = facStatInfo[str(num)]
batLineup = batFaction.getBatlineup(num)
- hurtStatDict = batLineup.hurtStatDict
- defStatDict = batLineup.defStatDict
- cureStatDict = batLineup.cureStatDict
GameWorld.DebugLog("阵容明细: faction=%s,num=%s" % (faction, num))
- 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)
+ for posNum, objID in batLineup.posObjIDDict.items():
+ batObj = batObjMgr.getBatObj(objID)
+ if not batObj:
+ continue
+ objID = batObj.GetID()
+ npcID = batObj.GetNPCID()
+ heroID = batObj.GetHeroID()
+ atkHurt = batObj.hurtStat
+ defHurt = batObj.defStat
+ cureHP = batObj.cureStat
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))
+ % (posNum, objID, npcID, heroID, batObj.GetHP(), batObj.GetMaxHP(), atkHurt, defHurt, cureHP))
lineupStatInfo[str(posNum)] = {"ObjID":objID, "HeroID":heroID, "NPCID":npcID, "AtkHurt":atkHurt, "DefHurt":defHurt, "CureHP":cureHP}
awardItemList = []
playerID = turnFight.playerID
if playerID:
curPlayer = turnFight.curPlayer
- isWin = (winFaction == Def_FactionA)
+ isWin = (winFaction == ChConfig.Def_FactionA)
# 主线小怪
if turnFight.mapID == ChConfig.Def_FBMapID_Main:
OnOver_MainLevel(curPlayer, isWin, awardItemList)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index c0cbe0f..71f3b86 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -184,8 +184,6 @@
}
# 属性ID对应0418刷新类型 {属性ID:[刷新同步类型, 是否支持超20亿的大数值], ...}
-# 卡牌项目玩家/主公属性仅为中间层属性,并非最终属性,最终属性体现在卡牌上,暂定全部前端自己算
-# 所以仅配置战斗场景需要同步的属性即可
CDBRefresh_AttrIDDict = {
AttrID_MaxHP:[IPY_PlayerDefine.CDBPlayerRefresh_MaxHP, 1],
AttrID_HP:[IPY_PlayerDefine.CDBPlayerRefresh_HP, 1],
@@ -772,6 +770,8 @@
Def_Skill_Effect_BoomSeedHurt = 804 # BUFF种子单层伤害
Def_Skill_Effect_StoreBlood = 809 # 将期间受到的伤害总值,用于最后回血,不影响伤害
Def_Skill_Effect_AttackReplace = 1009 #攻击计算,野外小怪伤害替换1010 (2018-03-07增加精英怪)
+Def_Skill_Effect_Cure = 1000 #治疗
+Def_Skill_Effect_Anger = 1001 #怒气增减偷
Def_Skill_Effect_Attack = 1010 #攻击计算
Def_Skill_Effect_LayerCnt = 1011 # BUFF层级数量 A值层数;B值:10位-是否非叠加属性,个位-层数处理方式0递增1递减;C值: 是否攻击减层
Def_Skill_Effect_MasterBuff = 1012 # 主从技能(同步buff持续时间)
@@ -951,6 +951,20 @@
#伤害类型
(
+HurtType_Fail, # 失败 - 如概率没有触发 0
+HurtType_Normal, # 普通伤害 1
+HurtTYpe_Recovery, # 回血 2
+HurtType_3,
+HurtType_4,
+HurtType_Parry, # 格挡 5
+HurtType_IgnoreDef, # 无视防御 6
+HurtType_SuperHit, # 暴击 7
+HurtType_8,
+HurtType_Miss, # 闪避 9
+) = range(10)
+
+#伤害类型
+(
Def_HurtType_Normal, # 普通伤害 1
Def_HurtTYpe_Recovery, # 回复 2
Def_HurtType_BounceHurt, # 反弹伤害 3
@@ -969,7 +983,7 @@
Def_HurtType_ThumpHit, # 重击 16
Def_HurtType_Yinji, # 印记 17
Def_HurtType_Burn, # 灼烧 18
-) = range(1, 19)
+) = range(1001, 1001 + 18)
#Def_HurtType_SuckBlood, # 吸血
(
@@ -1319,6 +1333,24 @@
Def_Skill_HappenState_LuckyHit = 0x0004 # 必会心一击
Def_Skill_HappenState_ThumpHit = 0x0008 # 必重击
+# 技能目标 - 瞄准范围
+(
+SkillTagAim_All, # 全部 0
+SkillTagAim_Relative, # 对位位置 1
+SkillTagAim_FrontRow, # 前排 2
+SkillTagAim_BackRow, # 后排 3
+SkillTagAim_Vertical, # 竖排/纵排 4
+SkillTagAim_Self, # 自己 5
+SkillTagAim_MainSkill, # 继承主技能目标 6
+) = range(7)
+
+# 技能目标 - 细分
+(
+SkillTagAffect_None, # 无 0
+SkillTagAffect_HPLowest, # 血量最低 1
+SkillTagAffect_HPHighest, # 血量最高 2
+SkillTagAffect_Death, # 死亡单位 3
+) = range(4)
#技能施法目标
Def_UseSkillAim_Type = 3
@@ -1827,10 +1859,9 @@
Def_NstNull, Def_NstMoving, Def_NstDead, Def_NstAttack = range(4)
#-------------------------------#副本相关#------------------------
-# 主线小怪
-Def_FBMapID_Main = 1
-# 主线Boss
-Def_FBMapID_MainBoss = 2
+
+Def_FBMapID_Main = 1 # 主线小怪
+Def_FBMapID_MainBoss = 2 # 主线Boss
#创角新手村地图ID列表
Def_CreatRoleMapIDList = [10000]
@@ -2278,6 +2309,10 @@
DropOwnerType_Contend, # 争夺 8 第一个攻击的获得归属,击杀当前归属者的玩家成为新归属者
DropOwnerType_RankHurtPlayer, # 个人伤血排行奖励归属 9 根据玩家个人伤血排行给奖励,伤血不重置
) = range(10)
+
+#阵营
+Def_FactionA = 1
+Def_FactionB = 2
#------------------------------------------------
#技能类型
@@ -3022,7 +3057,8 @@
TurnBattleType_Normal, # 常规攻击
TurnBattleType_Combo, # 连击
TurnBattleType_AtkBack, # 反击
-) = range(3)
+TurnBattleType_Pursue , # 追击
+) = range(4)
Def_PerTurnTick = 1000 # 每回合等同于常规tick时长
@@ -4295,7 +4331,8 @@
#主线
Def_PDict_UnXiantaoCntExp = "UnXiantaoCntExp" # 累计未结算经验的战锤数
-Def_PDict_UnXiantaoCntEquip = "UnXiantaoCntEquip" # 累计未结算掉落的战锤数
+Def_PDict_UnXiantaoCntEquip = "UnXiantaoCntEquip" # 累计未结算装备掉落的战锤数
+Def_PDict_UnXiantaoCntBooty = "UnXiantaoCntBooty_%s" # 累计未结算战利品掉落的战锤数,参数(itemID)
Def_PDict_BootyDropToday = "BootyDropToday_%s" # 今日已累计掉落战利品数量,参数(itemID)
#-------------------------------------------------------------------------------
@@ -5103,6 +5140,16 @@
) = range(27)
+# 回合卡牌
+(
+Def_SkillFuncType_Common, #0为通用技能
+Def_SkillFuncType_TurnNormaSkill, #1 普攻技能
+Def_SkillFuncType_AngerSkill, #2 怒气技能
+Def_SkillFuncType_PotentialSkill, #3 潜能技能
+Def_SkillFuncType_AtkbackSkill, #4 反击技能
+) = range(5)
+
+# MMO项目 - 先保留,重新定义从1000开始,后续可陆续删除
(Def_SkillFuncType_Common, #0为通用技能
Def_SkillFuncType_FbSkill, #1为法宝功能获得的主动技能
Def_SkillFuncType_FbPassiveSkill, #2为法宝功能获得的被动技能
@@ -5126,8 +5173,7 @@
Def_SkillFuncType_ShentongSkill, #20 神通技能
Def_SkillFuncType_ElfSkill, #21 精怪技能
Def_SkillFuncType_GatherTheSoul, #22 聚魂技能
-Def_SkillFuncType_TurnNormaSkill, #23 回合普攻技能
-) = range(24)
+) = range(1000, 1000 + 23)
# 受技能效果完全影响的怪, 对应 Def_BattleRelationType_CommNoBoss
Def_SkillAttack_NPCIsBoss = [ Def_NPCType_Ogre_Normal , #平凡小怪 0 # c++ 定义为普通NPC视野刷新
@@ -5154,24 +5200,6 @@
ExpRateLimitType_Recover, # 资源找回
ExpRateLimitType_Sweep, # 扫荡
) = range(2)
-
-# 技能功能类对应战斗力模块
-Def_SkillFuncType_MFPType={
- Def_SkillFuncType_FbSkill:ShareDefine.Def_MFPType_MagicWeapon1,
- Def_SkillFuncType_FbPassiveSkill:ShareDefine.Def_MFPType_MagicWeapon2,
- Def_SkillFuncType_FbSPSkill:ShareDefine.Def_MFPType_MagicWeapon1,
- Def_SkillFuncType_GiftSkill:ShareDefine.Def_MFPType_Role,
-
- Def_SkillFuncType_HorseSkill:ShareDefine.Def_MFPType_Horse,
- Def_SkillFuncType_PetSkill:ShareDefine.Def_MFPType_Pet,
- Def_SkillFuncType_PetOwnerSkill:ShareDefine.Def_MFPType_Pet,
- Def_SkillFuncType_GWSkill:ShareDefine.Def_MFPType_Prestige,
- Def_SkillFuncType_SuiteSkill:ShareDefine.Def_MFPType_Equip,
- Def_SkillFuncType_TitleSkill:ShareDefine.Def_MFPType_Dienstgrad,
- Def_SkillFuncType_LianTiSkill:ShareDefine.Def_MFPType_LianTi,
- Def_SkillFuncType_ShentongSkill:ShareDefine.Def_MFPType_Shentong,
- }
-
# 投资理财类型,和前端对应,从7开始
InvestTypeList = (
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index c44e72b..8c1dd37 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -49840,6 +49840,142 @@
#------------------------------------------------------
+# B4 29 Buff消失 #tagSCBuffDel
+
+class tagSCBuffDel(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("Cmd", c_ubyte),
+ ("SubCmd", c_ubyte),
+ ("ObjID", c_int),
+ ("BuffID", c_int),
+ ("RelatedSkillID", c_int), # 关联的技能ID,一般是主技能ID或由于某个技能释放引起的buff变更
+ ]
+
+ def __init__(self):
+ self.Clear()
+ self.Cmd = 0xB4
+ self.SubCmd = 0x29
+ 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 = 0x29
+ self.ObjID = 0
+ self.BuffID = 0
+ self.RelatedSkillID = 0
+ return
+
+ def GetLength(self):
+ return sizeof(tagSCBuffDel)
+
+ def GetBuffer(self):
+ return string_at(addressof(self), self.GetLength())
+
+ def OutputString(self):
+ DumpString = '''// B4 29 Buff消失 //tagSCBuffDel:
+ Cmd:%s,
+ SubCmd:%s,
+ ObjID:%d,
+ BuffID:%d,
+ RelatedSkillID:%d
+ '''\
+ %(
+ self.Cmd,
+ self.SubCmd,
+ self.ObjID,
+ self.BuffID,
+ self.RelatedSkillID
+ )
+ return DumpString
+
+
+m_NAtagSCBuffDel=tagSCBuffDel()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCBuffDel.Cmd,m_NAtagSCBuffDel.SubCmd))] = m_NAtagSCBuffDel
+
+
+#------------------------------------------------------
+# B4 28 Buff刷新 #tagSCBuffRefresh
+
+class tagSCBuffRefresh(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("Cmd", c_ubyte),
+ ("SubCmd", c_ubyte),
+ ("ObjID", c_int), # 谁身上的buff
+ ("BuffID", c_int), # buffID,某个obj上的唯一buffID,不同的buffID可能skillID相同
+ ("SkillID", c_int), # 该buff对应技能表ID
+ ("RelatedSkillID", c_int), # 关联的技能ID,一般是主技能ID或由于某个技能释放引起的buff变更
+ ("LastTime", c_int), # 剩余时长毫秒/回合数
+ ("Layer", c_ushort), # 层数,不需要默认0
+ ("OwnerID", c_int), # buff来源者,即施法方
+ ]
+
+ def __init__(self):
+ self.Clear()
+ self.Cmd = 0xB4
+ self.SubCmd = 0x28
+ 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 = 0x28
+ self.ObjID = 0
+ self.BuffID = 0
+ self.SkillID = 0
+ self.RelatedSkillID = 0
+ self.LastTime = 0
+ self.Layer = 0
+ self.OwnerID = 0
+ return
+
+ def GetLength(self):
+ return sizeof(tagSCBuffRefresh)
+
+ def GetBuffer(self):
+ return string_at(addressof(self), self.GetLength())
+
+ def OutputString(self):
+ DumpString = '''// B4 28 Buff刷新 //tagSCBuffRefresh:
+ Cmd:%s,
+ SubCmd:%s,
+ ObjID:%d,
+ BuffID:%d,
+ SkillID:%d,
+ RelatedSkillID:%d,
+ LastTime:%d,
+ Layer:%d,
+ OwnerID:%d
+ '''\
+ %(
+ self.Cmd,
+ self.SubCmd,
+ self.ObjID,
+ self.BuffID,
+ self.SkillID,
+ self.RelatedSkillID,
+ self.LastTime,
+ self.Layer,
+ self.OwnerID
+ )
+ return DumpString
+
+
+m_NAtagSCBuffRefresh=tagSCBuffRefresh()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCBuffRefresh.Cmd,m_NAtagSCBuffRefresh.SubCmd))] = m_NAtagSCBuffRefresh
+
+
+#------------------------------------------------------
# B4 12 删除恶意攻击玩家 #tagMCDelMaliciousAtkPlayer
class tagMCDelMaliciousAtkPlayer(Structure):
@@ -50032,6 +50168,90 @@
m_NAtagMCNPCSkillWarn=tagMCNPCSkillWarn()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCNPCSkillWarn.Head.Cmd,m_NAtagMCNPCSkillWarn.Head.SubCmd))] = m_NAtagMCNPCSkillWarn
+
+
+#------------------------------------------------------
+# B4 18 对象属性刷新展示 #tagSCObjPropertyRefreshView
+
+class tagSCObjPropertyRefreshView(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("Cmd", c_ubyte),
+ ("SubCmd", c_ubyte),
+ ("ObjID", c_int),
+ ("RefreshType", c_ushort), # 同0418刷新类型,如血量、怒气
+ ("Value", c_int), # 更新值
+ ("ValueEx", c_int), # 更新值,如果是大数值的此值为整除亿部分
+ ("DiffType", c_ubyte), # 变化类型,0-减少;1-增加
+ ("DiffValue", c_int), # 变化值
+ ("DiffValueEx", c_int), # 变化值,如果是大数值的此值为整除亿部分
+ ("SkillID", c_int), # 使用的技能表ID
+ ("RelatedSkillID", c_int), # 关联的技能ID,一般是主技能ID,非主技能额外触发的为0
+ ]
+
+ def __init__(self):
+ self.Clear()
+ self.Cmd = 0xB4
+ self.SubCmd = 0x18
+ 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 = 0x18
+ self.ObjID = 0
+ self.RefreshType = 0
+ self.Value = 0
+ self.ValueEx = 0
+ self.DiffType = 0
+ self.DiffValue = 0
+ self.DiffValueEx = 0
+ self.SkillID = 0
+ self.RelatedSkillID = 0
+ return
+
+ def GetLength(self):
+ return sizeof(tagSCObjPropertyRefreshView)
+
+ def GetBuffer(self):
+ return string_at(addressof(self), self.GetLength())
+
+ def OutputString(self):
+ DumpString = '''// B4 18 对象属性刷新展示 //tagSCObjPropertyRefreshView:
+ Cmd:%s,
+ SubCmd:%s,
+ ObjID:%d,
+ RefreshType:%d,
+ Value:%d,
+ ValueEx:%d,
+ DiffType:%d,
+ DiffValue:%d,
+ DiffValueEx:%d,
+ SkillID:%d,
+ RelatedSkillID:%d
+ '''\
+ %(
+ self.Cmd,
+ self.SubCmd,
+ self.ObjID,
+ self.RefreshType,
+ self.Value,
+ self.ValueEx,
+ self.DiffType,
+ self.DiffValue,
+ self.DiffValueEx,
+ self.SkillID,
+ self.RelatedSkillID
+ )
+ return DumpString
+
+
+m_NAtagSCObjPropertyRefreshView=tagSCObjPropertyRefreshView()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCObjPropertyRefreshView.Cmd,m_NAtagSCObjPropertyRefreshView.SubCmd))] = m_NAtagSCObjPropertyRefreshView
#------------------------------------------------------
@@ -51241,6 +51461,8 @@
("Cmd", c_ubyte),
("SubCmd", c_ubyte),
("ObjID", c_int),
+ ("KillerObjID", c_int), # 被谁击杀的,可能为0
+ ("SkillID", c_int), # 被什么技能击杀,可能为0
]
def __init__(self):
@@ -51258,6 +51480,8 @@
self.Cmd = 0xB4
self.SubCmd = 0x22
self.ObjID = 0
+ self.KillerObjID = 0
+ self.SkillID = 0
return
def GetLength(self):
@@ -51270,12 +51494,16 @@
DumpString = '''// B4 22 回合战斗对象死亡 //tagMCTurnFightObjDead:
Cmd:%s,
SubCmd:%s,
- ObjID:%d
+ ObjID:%d,
+ KillerObjID:%d,
+ SkillID:%d
'''\
%(
self.Cmd,
self.SubCmd,
- self.ObjID
+ self.ObjID,
+ self.KillerObjID,
+ self.SkillID
)
return DumpString
@@ -51569,6 +51797,251 @@
#------------------------------------------------------
+# B4 26 回合战斗标签 #tagSCTurnFightTag
+
+class tagSCTurnFightTag(Structure):
+ Head = tagHead()
+ Len = 0 #(BYTE Len)
+ Tag = "" #(String Tag)// 标签,释放技能的标签格式: Skill_objID_skillID,其他标签格式可再扩展
+ Sign = 0 #(BYTE Sign)// 0-标签头;1-标签尾;
+ data = None
+
+ def __init__(self):
+ self.Clear()
+ self.Head.Cmd = 0xB4
+ self.Head.SubCmd = 0x26
+ return
+
+ def ReadData(self, _lpData, _pos=0, _Len=0):
+ self.Clear()
+ _pos = self.Head.ReadData(_lpData, _pos)
+ self.Len,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ self.Tag,_pos = CommFunc.ReadString(_lpData, _pos,self.Len)
+ self.Sign,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ return _pos
+
+ def Clear(self):
+ self.Head = tagHead()
+ self.Head.Clear()
+ self.Head.Cmd = 0xB4
+ self.Head.SubCmd = 0x26
+ self.Len = 0
+ self.Tag = ""
+ self.Sign = 0
+ return
+
+ def GetLength(self):
+ length = 0
+ length += self.Head.GetLength()
+ length += 1
+ length += len(self.Tag)
+ length += 1
+
+ return length
+
+ def GetBuffer(self):
+ data = ''
+ data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+ data = CommFunc.WriteBYTE(data, self.Len)
+ data = CommFunc.WriteString(data, self.Len, self.Tag)
+ data = CommFunc.WriteBYTE(data, self.Sign)
+ return data
+
+ def OutputString(self):
+ DumpString = '''
+ Head:%s,
+ Len:%d,
+ Tag:%s,
+ Sign:%d
+ '''\
+ %(
+ self.Head.OutputString(),
+ self.Len,
+ self.Tag,
+ self.Sign
+ )
+ return DumpString
+
+
+m_NAtagSCTurnFightTag=tagSCTurnFightTag()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCTurnFightTag.Head.Cmd,m_NAtagSCTurnFightTag.Head.SubCmd))] = m_NAtagSCTurnFightTag
+
+
+#------------------------------------------------------
+# B4 27 使用技能 #tagSCUseSkill
+
+class tagSCUseSkillHurt(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("ObjID", c_int),
+ ("AttackTypes", c_int), # 飘血类型汇总,支持多种类型并存,如无视防御且暴击同时被格挡,二进制或运算最终值;0-失败;1-普通;2-回血;5-格挡;6-无视防御;7-暴击;9-闪避
+ ("HurtHP", c_int), # 飘血值,求余亿部分
+ ("HurtHPEx", c_int), # 飘血值,整除亿部分
+ ("CurHP", c_int), # 更新剩余血量,求余亿部分
+ ("CurHPEx", c_int), # 更新剩余血量,整除亿部分
+ ("SuckHP", c_int), # 本次伤害转化的吸血量
+ ("BounceHP", c_int), # 本次伤害反弹的伤害量
+ ]
+
+ def __init__(self):
+ self.Clear()
+ 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.ObjID = 0
+ self.AttackTypes = 0
+ self.HurtHP = 0
+ self.HurtHPEx = 0
+ self.CurHP = 0
+ self.CurHPEx = 0
+ self.SuckHP = 0
+ self.BounceHP = 0
+ return
+
+ def GetLength(self):
+ return sizeof(tagSCUseSkillHurt)
+
+ def GetBuffer(self):
+ return string_at(addressof(self), self.GetLength())
+
+ def OutputString(self):
+ DumpString = '''// B4 27 使用技能 //tagSCUseSkill:
+ ObjID:%d,
+ AttackTypes:%d,
+ HurtHP:%d,
+ HurtHPEx:%d,
+ CurHP:%d,
+ CurHPEx:%d,
+ SuckHP:%d,
+ BounceHP:%d
+ '''\
+ %(
+ self.ObjID,
+ self.AttackTypes,
+ self.HurtHP,
+ self.HurtHPEx,
+ self.CurHP,
+ self.CurHPEx,
+ self.SuckHP,
+ self.BounceHP
+ )
+ return DumpString
+
+
+class tagSCUseSkill(Structure):
+ Head = tagHead()
+ ObjID = 0 #(DWORD ObjID)
+ PMType = 0 #(BYTE PMType)// 物法类型 0或1-物理;2-法术
+ BattleType = 0 #(BYTE BattleType)// 战斗类型 0-常规;1-连击;2-反击;3-追击
+ CurHP = 0 #(DWORD CurHP)// 释放技能后剩余血量,吸血、反弹可能引起变化,求余亿部分
+ CurHPEx = 0 #(DWORD CurHPEx)// 释放技能后剩余血量,吸血、反弹可能引起变化,整除亿部分
+ SkillID = 0 #(DWORD SkillID)
+ HurtCount = 0 #(BYTE HurtCount)//伤害数目
+ HurtList = list() #(vector<tagSCUseSkillHurt> HurtList)//size = HurtCount
+ data = None
+
+ def __init__(self):
+ self.Clear()
+ self.Head.Cmd = 0xB4
+ self.Head.SubCmd = 0x27
+ return
+
+ def ReadData(self, _lpData, _pos=0, _Len=0):
+ self.Clear()
+ _pos = self.Head.ReadData(_lpData, _pos)
+ self.ObjID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+ self.PMType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ self.BattleType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ self.CurHP,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+ self.CurHPEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+ self.SkillID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+ self.HurtCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ for i in range(self.HurtCount):
+ temHurtList = tagSCUseSkillHurt()
+ _pos = temHurtList.ReadData(_lpData, _pos)
+ self.HurtList.append(temHurtList)
+ return _pos
+
+ def Clear(self):
+ self.Head = tagHead()
+ self.Head.Clear()
+ self.Head.Cmd = 0xB4
+ self.Head.SubCmd = 0x27
+ self.ObjID = 0
+ self.PMType = 0
+ self.BattleType = 0
+ self.CurHP = 0
+ self.CurHPEx = 0
+ self.SkillID = 0
+ self.HurtCount = 0
+ self.HurtList = list()
+ return
+
+ def GetLength(self):
+ length = 0
+ length += self.Head.GetLength()
+ length += 4
+ length += 1
+ length += 1
+ length += 4
+ length += 4
+ length += 4
+ length += 1
+ for i in range(self.HurtCount):
+ length += self.HurtList[i].GetLength()
+
+ return length
+
+ def GetBuffer(self):
+ data = ''
+ data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+ data = CommFunc.WriteDWORD(data, self.ObjID)
+ data = CommFunc.WriteBYTE(data, self.PMType)
+ data = CommFunc.WriteBYTE(data, self.BattleType)
+ data = CommFunc.WriteDWORD(data, self.CurHP)
+ data = CommFunc.WriteDWORD(data, self.CurHPEx)
+ data = CommFunc.WriteDWORD(data, self.SkillID)
+ data = CommFunc.WriteBYTE(data, self.HurtCount)
+ for i in range(self.HurtCount):
+ data = CommFunc.WriteString(data, self.HurtList[i].GetLength(), self.HurtList[i].GetBuffer())
+ return data
+
+ def OutputString(self):
+ DumpString = '''
+ Head:%s,
+ ObjID:%d,
+ PMType:%d,
+ BattleType:%d,
+ CurHP:%d,
+ CurHPEx:%d,
+ SkillID:%d,
+ HurtCount:%d,
+ HurtList:%s
+ '''\
+ %(
+ self.Head.OutputString(),
+ self.ObjID,
+ self.PMType,
+ self.BattleType,
+ self.CurHP,
+ self.CurHPEx,
+ self.SkillID,
+ self.HurtCount,
+ "..."
+ )
+ return DumpString
+
+
+m_NAtagSCUseSkill=tagSCUseSkill()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCUseSkill.Head.Cmd,m_NAtagSCUseSkill.Head.SubCmd))] = m_NAtagSCUseSkill
+
+
+#------------------------------------------------------
# B5 04 拍卖行新上架拍品 #tagGCAddAuctionItemInfo
class tagGCAddAuctionItem(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Hero.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Hero.py
index 95f6e59..40f4d30 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Hero.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Hero.py
@@ -157,8 +157,10 @@
def __oneKeyLineup(curPlayer, msgList):
## 阵容上阵: Hero f 阵容ID [武将ID ...]
lineupID = msgList[1] if len(msgList) > 1 else 0
- heroIDList = list(set(msgList[2:])) # 去重,单阵容武将ID不能重复
-
+ heroIDList = []
+ for heroID in msgList[2:]: # 去重,单阵容武将ID不能重复
+ if heroID not in heroIDList:
+ heroIDList.append(heroID)
if lineupID not in ShareDefine.LineupList:
GameWorld.DebugAnswer(curPlayer, "不存在该阵容: %s" % lineupID)
return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MainLevel.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MainLevel.py
index 8a608cc..1446e64 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MainLevel.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MainLevel.py
@@ -25,7 +25,7 @@
if not gmList:
GameWorld.DebugAnswer(curPlayer, "重置主线: MainLevel 0")
GameWorld.DebugAnswer(curPlayer, "设置主线: MainLevel 章节 关卡 波")
- GameWorld.DebugAnswer(curPlayer, "测试掉落: MainLevel d 击杀数")
+ GameWorld.DebugAnswer(curPlayer, "测试掉落: MainLevel d 战锤数")
GameWorld.DebugAnswer(curPlayer, "重置战利: MainLevel b 0")
GameWorld.DebugAnswer(curPlayer, "设置战利: MainLevel b 战利品ID 已掉落个数")
return
@@ -33,8 +33,8 @@
value = gmList[0]
if value == "d":
- killCnt = gmList[1] if len(gmList) > 1 else 1
- GameLogic_MainLevel.GMTestKillDrop(curPlayer, killCnt)
+ unXiantao = gmList[1] if len(gmList) > 1 else 1
+ GameLogic_MainLevel.GMTestKillDrop(curPlayer, unXiantao)
return
if value == "b":
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py
index 2f512de..f3dd9cc 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py
@@ -533,9 +533,9 @@
else:
sendPack.Value = value
sendPack.ValueEx = 0
- turnFight = TurnAttack.GetTurnFightMgr().getNPCTurnFight(gameObj.GetID())
- if turnFight:
- turnFight.addBatPack(sendPack)
- return
+ #turnFight = TurnAttack.GetTurnFightMgr().getTurnFight(gameObj.GetTFGUID())
+ #if turnFight:
+ # turnFight.addBatPack(sendPack)
+ # return
gameObj.NotifyAll(sendPack.GetBuffer(), sendPack.GetLength())
return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
index f1661c3..41dd4bf 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
@@ -2409,25 +2409,14 @@
return callFunc(curPlayer, mapID, funcLineID, tagType, tagID, valueList)
-def OnPlayerLineupAttackSuccess(curPlayer, atkObj, defObj, curSkill, mapID, funcLineID):
- ## 回合战斗主动发起的玩家阵容释放技能成功
- do_FBLogic_ID = __GetFBLogic_MapID(mapID)
-
- callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "OnPlayerLineupAttackSuccess"))
-
- if callFunc:
- callFunc(curPlayer, atkObj, defObj, curSkill, mapID, funcLineID)
-
- return
-
-def OnPlayerLineupAttackResult(curPlayer, atkObj, defObj, curSkill, mapID, funcLineID):
- ## 回合战斗主动发起的玩家阵容攻击结果额外处理
+def OnPlayerLineupAttackResult(curPlayer, atkObj, killObjIDList, useSkill, mapID, funcLineID):
+ ## 回合战斗主动发起的玩家阵容攻击结果额外处理 ,一般处理副本相关的掉落、奖励等
do_FBLogic_ID = __GetFBLogic_MapID(mapID)
callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "OnPlayerLineupAttackResult"))
if callFunc:
- callFunc(curPlayer, atkObj, defObj, curSkill, mapID, funcLineID)
+ callFunc(curPlayer, atkObj, killObjIDList, useSkill, mapID, funcLineID)
return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py
index 72f075a..6cb2c29 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py
@@ -18,17 +18,16 @@
import ChConfig
import GameWorld
import ShareDefine
-import SkillCommon
import IpyGameDataPY
import PlayerControl
import ChPyNetSendPack
import ItemControler
import IPY_GameWorld
import NetPackCommon
-import TurnAttack
import ItemCommon
import NPCCommon
import ChEquip
+import ObjPool
import random
@@ -43,6 +42,7 @@
def ResetBootyDropToday(curPlayer):
bootyItemIDList = GetBootyItemIDList()
for itemID in bootyItemIDList:
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntBooty % itemID, 0)
if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BootyDropToday % itemID):
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BootyDropToday % itemID, 0)
SyncDropBootyInfo(curPlayer)
@@ -64,63 +64,21 @@
ipyData = ipyDataMgr.GetMainChapterByIndex(chapterCount - 1)
return [booty[0] for booty in ipyData.GetDailyBootyUpperList()]
-def OnPlayerLineupAttackSuccess(curPlayer, atkObj, defObj, curSkill, mapID, funcLineID):
- ## 回合战斗主动发起的玩家阵容释放技能成功
+def OnPlayerLineupAttackResult(curPlayer, atkObj, killObjIDList, useSkill, mapID, funcLineID):
+ ## 回合战斗主动发起的玩家阵容攻击结果额外处理 ,一般处理副本相关的掉落、奖励等
if mapID == ChConfig.Def_FBMapID_Main:
- __doCostZhanchui(curPlayer, atkObj, curSkill)
+ __doKillAward(curPlayer, atkObj, killObjIDList)
return
-def __doCostZhanchui(curPlayer, atkObj, curSkill):
- ## 扣除战锤消耗
- costZhanchui = 0
- isXP = SkillCommon.isAngerSkill(curSkill)
- turnBattleType = atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnBattleType)
- if isXP:
- costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 2)
- elif turnBattleType == ChConfig.TurnBattleType_Combo:
- costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 3)
- elif turnBattleType == ChConfig.TurnBattleType_AtkBack:
- costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 4)
- elif SkillCommon.isTurnNormalSkill(curSkill):
- costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 1)
-
- if costZhanchui <= 0:
- return
-
- fightPoint = max(curPlayer.GetFightPoint(), 1) # 主线战斗消耗倍值,默认1
- costZhanchuiTotal = costZhanchui * fightPoint
- if not PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, costZhanchuiTotal, isNotify=False):
- # 不足时,有多少扣多少
- nowMoney = PlayerControl.GetMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao)
- PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, min(nowMoney, costZhanchuiTotal), isNotify=False)
-
- return
-
-def OnPlayerLineupAttackResult(curPlayer, atkObj, defObj, curSkill, mapID, funcLineID):
-
- if mapID == ChConfig.Def_FBMapID_Main:
- __doKillAward(curPlayer, atkObj, mapID, funcLineID)
-
- return
-
-def __doKillAward(curPlayer, atkObj, mapID, funcLineID):
+def __doKillAward(curPlayer, atkObj, killObjIDList):
## 计算击杀奖励
- turnFight = TurnAttack.GetTurnFightMgr().getNPCTurnFight(atkObj.GetID())
- if not turnFight:
+ if not killObjIDList:
+ GameWorld.DebugLog("没有击杀不需要处理!")
return
-
- unXiantaoCntExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntExp)
- if not turnFight.playerKillObjIDList:
- unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip)
- GameWorld.DebugLog("没有击杀不需要处理! unXiantaoCntExp=%s,unXiantaoCntEquip=%s" % (unXiantaoCntExp, unXiantaoCntEquip))
- return
- killCnt = len(turnFight.playerKillObjIDList)
- # 直接重置,防止异常时重复结算
- turnFight.playerKillObjIDList = []
-
# 结算经验
+ unXiantaoCntExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntExp)
if unXiantaoCntExp:
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntExp, 0)
perExp = IpyGameDataPY.GetFuncCfg("Mainline", 1) # 每个战锤增加经验
@@ -128,60 +86,68 @@
GameWorld.DebugLog("增加经验: totalExp=%s,unXiantaoCntExp=%s" % (totalExp, unXiantaoCntExp))
PlayerControl.PlayerControl(curPlayer).AddExp(totalExp, ShareDefine.Def_ViewExpType_KillNPC)
- __doMainDrop(curPlayer, killCnt)
+ __doMainDrop(curPlayer)
return
-def __doMainDrop(curPlayer, killCnt):
+def __doMainDrop(curPlayer):
# 装备掉落
__doDropEquip(curPlayer)
playerID = curPlayer.GetPlayerID()
- DailyBootyUpperList, BootyWeightList = [], []
+ DailyBootyUpperList = []
chapterID = PlayerControl.GetMainLevelNowInfo(curPlayer)[0]
chapterIpyData = IpyGameDataPY.GetIpyGameData("MainChapter", chapterID)
if chapterIpyData:
DailyBootyUpperList = chapterIpyData.GetDailyBootyUpperList()
- BootyWeightList = chapterIpyData.GetBootyWeightList()
-
- bootyDropUpperDict = {k:v for k, v in DailyBootyUpperList}
- GameWorld.DebugLog("可掉落战利品上限: chapterID=%s,%s,killCnt=%s" % (chapterID, bootyDropUpperDict, killCnt), playerID)
+
+ GameWorld.DebugLog("可掉落战利品上限: chapterID=%s, %s" % (chapterID, DailyBootyUpperList), playerID)
# 其他战利品掉落
- for _ in range(killCnt):
- dropInfo = GameWorld.GetResultByWeightList(BootyWeightList)
- if not dropInfo:
- continue
- itemID = dropInfo[0]
- if not itemID:
- GameWorld.DebugLog("本次不掉落战利品!", playerID)
- continue
- if itemID not in bootyDropUpperDict:
- GameWorld.DebugLog("该战利品未解锁! itemID=%s" % itemID, playerID)
+ bootyDropNeedDict = IpyGameDataPY.GetFuncEvalCfg("MainBootyDrop", 1, {})
+ bootyDropCntDict = IpyGameDataPY.GetFuncEvalCfg("MainBootyDrop", 2, {})
+ for itemID, dropUpper in DailyBootyUpperList:
+ if dropUpper <= 0:
continue
todyDropCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BootyDropToday % itemID)
- dropUpper = bootyDropUpperDict.get(itemID, 0)
if todyDropCnt >= dropUpper:
GameWorld.DebugLog("战利品已达今日掉落上限! itemID=%s,todyDropCnt=%s >= %s" % (itemID, todyDropCnt, dropUpper), playerID)
continue
+ if itemID not in bootyDropNeedDict or itemID not in bootyDropCntDict:
+ continue
+ dropOneNeed = bootyDropNeedDict[itemID]
+ unXiantaoCntBooty = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntBooty % itemID)
+ dropBootyCnt = unXiantaoCntBooty / dropOneNeed
+ if dropBootyCnt <= 0:
+ continue
- dropMin = dropInfo[1] if len(dropInfo) > 1 else 1
- dropMax = dropInfo[2] if len(dropInfo) > 2 else 1
+ dropCntRange = bootyDropCntDict[itemID]
+ if not isinstance(dropCntRange, (list, tuple)) or len(dropCntRange) != 2:
+ continue
+ dropMin = dropCntRange[0]
+ dropMax = dropCntRange[1]
- if dropMin == dropMax:
- dropCnt = dropMin
- else:
- dropCnt = random.randint(dropMin, dropMax)
- dropCnt = min(dropCnt, dropUpper - todyDropCnt)
+ dropCntTotal = 0
+ for _ in range(dropBootyCnt):
+ if dropMin == dropMax:
+ dropCnt = dropMin
+ else:
+ dropCnt = random.randint(dropMin, dropMax)
+ dropCntTotal += dropCnt
+ dropCntTotal = min(dropCntTotal, dropUpper - todyDropCnt)
+ if dropCntTotal <= 0:
+ continue
- GameWorld.DebugLog("掉落战利品! itemID=%s,dropCnt=%s" % (itemID, dropCnt), playerID)
- curItem = ItemControler.GetOutPutItemObj(itemID, dropCnt, False, curPlayer=curPlayer)
+ GameWorld.DebugLog("掉落战利品! itemID=%s,unXiantaoCntBooty=%s,次数=%s,dropCntTotal=%s" % (itemID, unXiantaoCntBooty, dropBootyCnt, dropCntTotal), playerID)
+ curItem = ItemControler.GetOutPutItemObj(itemID, dropCntTotal, False, curPlayer=curPlayer)
if curItem == None:
continue
curItem.SetIsBind(1) # 为1时代表是掉落
if not ItemControler.DoLogic_PutItemInPack(curPlayer, curItem, packIndexList=[IPY_GameWorld.rptIdentify]):
continue
- SetBootyDropToday(curPlayer, itemID, todyDropCnt + dropCnt)
-
+ unXiantaoCntBooty = unXiantaoCntBooty % dropOneNeed
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntBooty % itemID, unXiantaoCntBooty)
+ SetBootyDropToday(curPlayer, itemID, todyDropCnt + dropCntTotal)
+
return
def __doDropEquip(curPlayer):
@@ -243,14 +209,23 @@
return
-def GMTestKillDrop(curPlayer, killCnt):
+def GMTestKillDrop(curPlayer, unXiantao):
## GM测试掉落
- unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip) + killCnt
+ unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip) + unXiantao
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntEquip, unXiantaoCntEquip)
- __doMainDrop(curPlayer, killCnt)
-
- unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip)
- GameWorld.DebugAnswer(curPlayer, "剩余未结算装备掉落战锤数:%s" % unXiantaoCntEquip)
+ GameWorld.DebugAnswer(curPlayer, "未结算装备战锤数: %s" % unXiantaoCntEquip)
+ chapterID = PlayerControl.GetMainLevelNowInfo(curPlayer)[0]
+ chapterIpyData = IpyGameDataPY.GetIpyGameData("MainChapter", chapterID)
+ if chapterIpyData:
+ DailyBootyUpperList = chapterIpyData.GetDailyBootyUpperList()
+ for itemID, upperCnt in DailyBootyUpperList:
+ if upperCnt <= 0:
+ continue
+ unXiantaoCntBooty = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntBooty % itemID) + unXiantao
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntBooty % itemID, unXiantaoCntBooty)
+ GameWorld.DebugAnswer(curPlayer, "未结算战利品(%s)战锤数: %s" % (itemID, unXiantaoCntBooty))
+
+ __doMainDrop(curPlayer)
return
#// B4 15 主线掉落物品操作 #tagCSMainDropItemOP
@@ -406,10 +381,11 @@
syncItemIDList = GetBootyItemIDList()
else:
syncItemIDList = [itemID]
- clientPack = ChPyNetSendPack.tagSCDropBootyInfo()
+ poolMgr = ObjPool.GetPoolMgr()
+ clientPack = poolMgr.acquire(ChPyNetSendPack.tagSCDropBootyInfo)
clientPack.DropBootyList = []
for itemID in syncItemIDList:
- dropBooty = ChPyNetSendPack.tagSCDropBooty()
+ dropBooty = poolMgr.acquire(ChPyNetSendPack.tagSCDropBooty)
dropBooty.ItemID = itemID
dropBooty.TodayDropCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BootyDropToday % itemID)
clientPack.DropBootyList.append(dropBooty)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldEvent.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldEvent.py
index 0b2a0a9..697275e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldEvent.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldEvent.py
@@ -26,6 +26,8 @@
import ShareDefine
import PlayerTeam
import PyGameData
+import BattleObj
+import ObjPool
import datetime
import time
@@ -265,6 +267,8 @@
#GameWorldActionControl.Dispose_DailyActionState()
#GameWorldActionControl.Dispose_FBStateTime()
PlayerOnline.OnMinute()
+ BattleObj.OnMinute()
+ ObjPool.OnMinute()
PlayerTeam.OnCheckTeamPlayerDisconnectTimeout(tick)
__CheckIpyDataRecycle(curTime)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index e39ca0d..dff0eec 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -56,8 +56,64 @@
("BYTE", "OPLimitInAct", 0),
),
+ "NPC":(
+ ("DWORD", "NPCID", 1),
+ ("char", "NPCName", 0),
+ ("BYTE", "Country", 0),
+ ("BYTE", "AtkDistType", 0),
+ ("WORD", "LV", 0),
+ ("DWORD", "Atk", 0),
+ ("DWORD", "Def", 0),
+ ("DWORD", "MaxHP", 0),
+ ("list", "SkillIDList", 0),
+ ("DWORD", "FinalDamPer", 0),
+ ("DWORD", "FinalDamPerDef", 0),
+ ("DWORD", "MissRate", 0),
+ ("DWORD", "MissRateDef", 0),
+ ("DWORD", "SuperHitRate", 0),
+ ("DWORD", "SuperHitRateDef", 0),
+ ("DWORD", "StunRate", 0),
+ ("DWORD", "StunRateDef", 0),
+ ("DWORD", "ComboRate", 0),
+ ("DWORD", "ComboRateDef", 0),
+ ("DWORD", "ParryRate", 0),
+ ("DWORD", "ParryRateDef", 0),
+ ("DWORD", "SuckHPPer", 0),
+ ("DWORD", "SuckHPPerDef", 0),
+ ("dict", "SpecAttrInfo", 0),
+ ),
+
+ "Skill":(
+ ("DWORD", "SkillID", 1),
+ ("DWORD", "SkillTypeID", 0),
+ ("WORD", "SkillMaxLV", 0),
+ ("char", "SkillName", 0),
+ ("BYTE", "FuncType", 0),
+ ("BYTE", "SkillType", 0),
+ ("BYTE", "HurtType", 0),
+ ("BYTE", "AtkType", 0),
+ ("BYTE", "TagAim", 0),
+ ("BYTE", "TagFriendly", 0),
+ ("BYTE", "TagAffect", 0),
+ ("BYTE", "TagCount", 0),
+ ("WORD", "HappenRate", 0),
+ ("WORD", "LastTime", 0),
+ ("WORD", "CoolDownTime", 0),
+ ("WORD", "Priority", 0),
+ ("DWORD", "EffectID1", 0),
+ ("list", "EffectValues1", 0),
+ ("DWORD", "EffectID2", 0),
+ ("list", "EffectValues2", 0),
+ ("DWORD", "EffectID3", 0),
+ ("list", "EffectValues3", 0),
+ ("DWORD", "ConnSkill", 0),
+ ("list", "EnhanceSkillList", 0),
+ ("DWORD", "FightPower", 0),
+ ),
+
"Hero":(
("DWORD", "HeroID", 1),
+ ("char", "Name", 0),
("BYTE", "Country", 0),
("BYTE", "Quality", 0),
("BYTE", "AtkDistType", 0),
@@ -161,7 +217,6 @@
"MainChapter":(
("BYTE", "ChapterID", 1),
("list", "DailyBootyUpperList", 0),
- ("list", "BootyWeightList", 0),
),
"MainLevel":(
@@ -730,33 +785,6 @@
("float", "AttrPer", 0),
("dict", "AttrSpecDict", 0),
("dict", "AttrExDict", 0),
- ),
-
- "NPCEx":(
- ("DWORD", "NPCID", 1),
- ("BYTE", "FightPowerLackAtkLimit", 0),
- ("DWORD", "SuppressFightPower", 0),
- ("BYTE", "AtkDistType", 0),
- ("DWORD", "Atk", 0),
- ("DWORD", "Def", 0),
- ("DWORD", "MaxHP", 0),
- ("list", "SkillIDList", 0),
- ("DWORD", "FinalHurtPer", 0),
- ("DWORD", "FinalHurtReducePer", 0),
- ("DWORD", "MissRate", 0),
- ("DWORD", "MissDefRate", 0),
- ("DWORD", "SuperHitRate", 0),
- ("DWORD", "SuperHitRateReduce", 0),
- ("DWORD", "FaintRate", 0),
- ("DWORD", "FaintDefRate", 0),
- ("DWORD", "ComboRate", 0),
- ("DWORD", "ComboDefRate", 0),
- ("DWORD", "ParryRate", 0),
- ("DWORD", "ParryDefRate", 0),
- ("DWORD", "ParryDamPer", 0),
- ("DWORD", "SuckHPPer", 0),
- ("DWORD", "SuckHPDefPer", 0),
- ("dict", "SpecAttrInfo", 0),
),
"NPCRealmStrengthen":(
@@ -2840,6 +2868,71 @@
def GetSortReverse(self): return self.attrTuple[6] # 是否倒序 BYTE
def GetOPLimitInAct(self): return self.attrTuple[7] # 活动期间限制队伍操作 BYTE
+# NPC表
+class IPY_NPC():
+
+ def __init__(self):
+ self.attrTuple = None
+ return
+
+ def GetNPCID(self): return self.attrTuple[0] # NPCID DWORD
+ def GetNPCName(self): return self.attrTuple[1] # 名称 char
+ def GetCountry(self): return self.attrTuple[2] # 国家 BYTE
+ def GetAtkDistType(self): return self.attrTuple[3] # 远近类型;1-近战;2-远程 BYTE
+ def GetLV(self): return self.attrTuple[4] # 等级 WORD
+ def GetAtk(self): return self.attrTuple[5] # 攻击力 DWORD
+ def GetDef(self): return self.attrTuple[6] # 防御值 DWORD
+ def GetMaxHP(self): return self.attrTuple[7] # 最大生命值,可超过20E DWORD
+ def GetSkillIDList(self): return self.attrTuple[8] # 技能ID列表 list
+ def GetFinalDamPer(self): return self.attrTuple[9] # 最终增伤 DWORD
+ def GetFinalDamPerDef(self): return self.attrTuple[10] # 最终减伤 DWORD
+ def GetMissRate(self): return self.attrTuple[11] # 闪避概率 DWORD
+ def GetMissRateDef(self): return self.attrTuple[12] # 抗闪避概率 DWORD
+ def GetSuperHitRate(self): return self.attrTuple[13] # 暴击概率 DWORD
+ def GetSuperHitRateDef(self): return self.attrTuple[14] # 抗暴击概率 DWORD
+ def GetStunRate(self): return self.attrTuple[15] # 击晕概率 DWORD
+ def GetStunRateDef(self): return self.attrTuple[16] # 抗击晕概率 DWORD
+ def GetComboRate(self): return self.attrTuple[17] # 连击概率 DWORD
+ def GetComboRateDef(self): return self.attrTuple[18] # 抗连击概率 DWORD
+ def GetParryRate(self): return self.attrTuple[19] # 格挡概率 DWORD
+ def GetParryRateDef(self): return self.attrTuple[20] # 抗格挡概率 DWORD
+ def GetSuckHPPer(self): return self.attrTuple[21] # 吸血比率 DWORD
+ def GetSuckHPPerDef(self): return self.attrTuple[22] # 抗吸血比率 DWORD
+ def GetSpecAttrInfo(self): return self.attrTuple[23] # 特殊属性信息 {"属性ID":值, ...} dict
+
+# 技能表
+class IPY_Skill():
+
+ def __init__(self):
+ self.attrTuple = None
+ return
+
+ def GetSkillID(self): return self.attrTuple[0] # 技能ID DWORD
+ def GetSkillTypeID(self): return self.attrTuple[1] # 技能TypeID DWORD
+ def GetSkillMaxLV(self): return self.attrTuple[2] # 最高等级 WORD
+ def GetSkillName(self): return self.attrTuple[3] # 技能名 char
+ def GetFuncType(self): return self.attrTuple[4] # 功能分类 BYTE
+ def GetSkillType(self): return self.attrTuple[5] # 技能类型 BYTE
+ def GetHurtType(self): return self.attrTuple[6] # 伤害类型 BYTE
+ def GetAtkType(self): return self.attrTuple[7] # 释放方式 BYTE
+ def GetTagAim(self): return self.attrTuple[8] # 瞄准位置 BYTE
+ def GetTagFriendly(self): return self.attrTuple[9] # 敌我目标 BYTE
+ def GetTagAffect(self): return self.attrTuple[10] # 目标细分 BYTE
+ def GetTagCount(self): return self.attrTuple[11] # 目标个数 BYTE
+ def GetHappenRate(self): return self.attrTuple[12] # 释放或添加几率 WORD
+ def GetLastTime(self): return self.attrTuple[13] # 持续时间 WORD
+ def GetCoolDownTime(self): return self.attrTuple[14] # 冷却时间 WORD
+ def GetPriority(self): return self.attrTuple[15] # 优先级 WORD
+ def GetEffectID1(self): return self.attrTuple[16] # 效果ID1 DWORD
+ def GetEffectValues1(self): return self.attrTuple[17] # 效果值列表1 list
+ def GetEffectID2(self): return self.attrTuple[18] # 效果ID2 DWORD
+ def GetEffectValues2(self): return self.attrTuple[19] # 效果值列表2 list
+ def GetEffectID3(self): return self.attrTuple[20] # 效果ID3 DWORD
+ def GetEffectValues3(self): return self.attrTuple[21] # 效果值列表3 list
+ def GetConnSkill(self): return self.attrTuple[22] # 关联技能 DWORD
+ def GetEnhanceSkillList(self): return self.attrTuple[23] # 触发技能ID列表 list
+ def GetFightPower(self): return self.attrTuple[24] # 技能战斗力 DWORD
+
# 武将表
class IPY_Hero():
@@ -2848,17 +2941,18 @@
return
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 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
- def GetFetterIDList(self): return self.attrTuple[11] # 羁绊ID列表 list
+ def GetName(self): return self.attrTuple[1] # 名称 char
+ def GetCountry(self): return self.attrTuple[2] # 国家 BYTE
+ def GetQuality(self): return self.attrTuple[3] # 品质 BYTE
+ def GetAtkDistType(self): return self.attrTuple[4] # 远近类型;1-近战;2-远程 BYTE
+ def GetSkinIDList(self): return self.attrTuple[5] # 皮肤ID列表 list
+ def GetNormalSkillID(self): return self.attrTuple[6] # 普攻技能ID DWORD
+ def GetAngerSkillID(self): return self.attrTuple[7] # 怒气技能ID DWORD
+ def GetAtkInheritPer(self): return self.attrTuple[8] # 攻击继承 WORD
+ def GetDefInheritPer(self): return self.attrTuple[9] # 防御继承 WORD
+ def GetHPInheritPer(self): return self.attrTuple[10] # 生命继承 WORD
+ def GetBatAttrDict(self): return self.attrTuple[11] # 其他战斗属性字典 {"属性ID":值, ...} dict
+ def GetFetterIDList(self): return self.attrTuple[12] # 羁绊ID列表 list
# 武将星级天赋表
class IPY_HeroTalent():
@@ -3010,8 +3104,7 @@
return
def GetChapterID(self): return self.attrTuple[0] # 章节ID BYTE
- def GetDailyBootyUpperList(self): return self.attrTuple[1] # 每日战利品掉落上限,[[物品ID,每日上限], ...] list
- def GetBootyWeightList(self): return self.attrTuple[2] # 战利品掉落权重,[[权重,物品ID,掉落个数下限, 上限], ...] list
+ def GetDailyBootyUpperList(self): return self.attrTuple[1] # 每日战利品掉落上限,[[物品ID,每日上限], ...] list
# 主线关卡表
class IPY_MainLevel():
@@ -3890,38 +3983,6 @@
def GetAttrPer(self): return self.attrTuple[5] # 对应等级表中的比例 float
def GetAttrSpecDict(self): return self.attrTuple[6] # 特殊属性值字典 {attrKey:value, ...} dict
def GetAttrExDict(self): return self.attrTuple[7] # 特殊属性值字典 {attrKey:value, ...} dict
-
-# NPC表扩展
-class IPY_NPCEx():
-
- def __init__(self):
- self.attrTuple = None
- return
-
- 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 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
- def GetSkillIDList(self): return self.attrTuple[7] # 技能ID列表 list
- def GetFinalHurtPer(self): return self.attrTuple[8] # 最终增伤 DWORD
- def GetFinalHurtReducePer(self): return self.attrTuple[9] # 最终减伤 DWORD
- def GetMissRate(self): return self.attrTuple[10] # 闪避概率 DWORD
- def GetMissDefRate(self): return self.attrTuple[11] # 抗闪避概率 DWORD
- def GetSuperHitRate(self): return self.attrTuple[12] # 暴击概率 DWORD
- def GetSuperHitRateReduce(self): return self.attrTuple[13] # 抗暴击概率 DWORD
- def GetFaintRate(self): return self.attrTuple[14] # 击晕概率 DWORD
- def GetFaintDefRate(self): return self.attrTuple[15] # 抗击晕概率 DWORD
- def GetComboRate(self): return self.attrTuple[16] # 连击概率 DWORD
- def GetComboDefRate(self): return self.attrTuple[17] # 抗连击概率 DWORD
- def GetParryRate(self): return self.attrTuple[18] # 格挡概率 DWORD
- def GetParryDefRate(self): return self.attrTuple[19] # 抗格挡概率 DWORD
- def GetParryDamPer(self): return self.attrTuple[20] # 格挡减伤比率 DWORD
- def GetSuckHPPer(self): return self.attrTuple[21] # 吸血比率 DWORD
- def GetSuckHPDefPer(self): return self.attrTuple[22] # 抗吸血比率 DWORD
- def GetSpecAttrInfo(self): return self.attrTuple[23] # 特殊属性信息 {"属性ID":值, ...} dict
# 成长型境界怪物表
class IPY_NPCRealmStrengthen():
@@ -7084,6 +7145,8 @@
self.__LoadFileData("DirtyList", onlyCheck)
self.__LoadFileData("DirtyName", onlyCheck)
self.__LoadFileData("FuncTeamSet", onlyCheck)
+ self.__LoadFileData("NPC", onlyCheck)
+ self.__LoadFileData("Skill", onlyCheck)
self.__LoadFileData("Hero", onlyCheck)
self.__LoadFileData("HeroTalent", onlyCheck)
self.__LoadFileData("HeroBreak", onlyCheck)
@@ -7159,7 +7222,6 @@
self.__LoadFileData("PlayerLV", onlyCheck)
self.__LoadFileData("SpecMapPlayerAttrFormat", onlyCheck)
self.__LoadFileData("GMAttr", onlyCheck)
- self.__LoadFileData("NPCEx", onlyCheck)
self.__LoadFileData("NPCRealmStrengthen", onlyCheck)
self.__LoadFileData("NPCStrengthen", onlyCheck)
self.__LoadFileData("NPCTimeLostHP", onlyCheck)
@@ -7603,6 +7665,20 @@
def GetFuncTeamSetByIndex(self, index):
self.CheckLoadData("FuncTeamSet")
return self.ipyFuncTeamSetCache[index]
+
+ def GetNPCCount(self):
+ self.CheckLoadData("NPC")
+ return self.ipyNPCLen
+ def GetNPCByIndex(self, index):
+ self.CheckLoadData("NPC")
+ return self.ipyNPCCache[index]
+
+ def GetSkillCount(self):
+ self.CheckLoadData("Skill")
+ return self.ipySkillLen
+ def GetSkillByIndex(self, index):
+ self.CheckLoadData("Skill")
+ return self.ipySkillCache[index]
def GetHeroCount(self):
self.CheckLoadData("Hero")
@@ -8128,13 +8204,6 @@
def GetGMAttrByIndex(self, index):
self.CheckLoadData("GMAttr")
return self.ipyGMAttrCache[index]
-
- def GetNPCExCount(self):
- self.CheckLoadData("NPCEx")
- return self.ipyNPCExLen
- def GetNPCExByIndex(self, index):
- self.CheckLoadData("NPCEx")
- return self.ipyNPCExCache[index]
def GetNPCRealmStrengthenCount(self):
self.CheckLoadData("NPCRealmStrengthen")
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 9080305..a6a329f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -129,12 +129,12 @@
return realmNPCIpyData.GetLV()
return curNPC.GetLV()
-def GetNPCDataEx(npcID):
- ## 获取NPC扩展数据表,可热更
- npcDataEx = IpyGameDataPY.GetIpyGameDataNotLog("NPCEx", npcID)
+def GetNPCDataPy(npcID):
+ ## 获取NPC数据表,py自定义的表,可热更
+ npcDataEx = IpyGameDataPY.GetIpyGameDataNotLog("NPC", npcID)
if not npcDataEx:
if False: # 不可能成立的条件,只为了 . 出代码提示
- npcDataEx = IpyGameDataPY.IPY_NPCEx()
+ npcDataEx = IpyGameDataPY.IPY_NPC()
return npcDataEx
return npcDataEx
@@ -142,11 +142,9 @@
def SetRealmLV(curNPC, realmLV): return curNPC.SetMAtkMin(realmLV) # NPC表中此字段含义改成境界等级
def GetIsLVSuppress(curNPC): return curNPC.GetWindDef() # 风防代表是否等级压制
def GetFightPowerLackAtkLimit(curNPC): # 战力不足限制攻击,默认不限制
- npcDataEx = GetNPCDataEx(curNPC.GetNPCID())
- return npcDataEx.GetFightPowerLackAtkLimit() if npcDataEx else 0
-def GetSuppressFightPower(curNPC):
- npcDataEx = GetNPCDataEx(curNPC.GetNPCID())
- return npcDataEx.GetSuppressFightPower() if npcDataEx else curNPC.GetThunderDef() # 雷防代表压制战力
+ return 0
+def GetSuppressFightPower(curNPC): # 压制战力
+ return 0
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() # 雷攻代表掉落归属类型
@@ -1124,19 +1122,18 @@
# 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)
+ #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), notifyClient)
- tfMgr.delNPCGUID(objID)
return
def GameServer_KillGameWorldBoss(bossID, killPlayerName, hurtValue, isNotify=True, killerIDList=[]):
@@ -2444,13 +2441,13 @@
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
+ #curNPC = self.__Instance
+ #objID = curNPC.GetID()
+ #turnFight = TurnAttack.GetTurnFightMgr().getNPCTurnFight(objID)
+ #if not turnFight:
+ # # 非回合制怪保留原通知
+ # curNPC.NotifyAppear()
+ # return
# 回合制怪不通知,统一由 // B4 24 回合战斗初始化 #tagSCTurnFightInit
return
@@ -2583,7 +2580,7 @@
ChConfig.AttrID_MaxHP:3000000000,
})
else:
- npcDataEx = GetNPCDataEx(curNPC.GetNPCID())
+ npcDataEx = GetNPCDataPy(curNPC.GetNPCID())
if not npcDataEx:
return
heroAttrDict.update({
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NetPackCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NetPackCommon.py
index 5ce5b67..a9b3f02 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NetPackCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NetPackCommon.py
@@ -31,6 +31,7 @@
import traceback
import ChGameToMapPyPack
from PyMongoDB.DBCommon import CommonDefine
+import ObjPool
#-------------------------------------------------------------------------------
#---全局变量---
@@ -227,6 +228,8 @@
Log("SendFakePack: clientPack Len = %s > %s"%(clientPack.GetLength(), len(innerPackData)))
#curPlayer.SendFakePack(innerPackData, len(innerPackData))
curPlayer.SendFakePack(clientPack.GetBuffer(), clientPack.GetLength())
+ ObjPool.GetPoolMgr().release(clientPack)
+ return
def SendFackPackOnline(clientPack, parseFunc=None, *args):
## 发送给全服在线玩家
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ObjPool.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ObjPool.py
new file mode 100644
index 0000000..062659f
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ObjPool.py
@@ -0,0 +1,498 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package ObjPool
+#
+# @todo:对象池管理
+# @author hxp
+# @date 2025-08-06
+# @version 1.0
+#
+# 详细描述: 对象池管理,建议对频繁创建的类使用对象池,如封包相关、战斗相关
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-08-06 18:30"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import PyGameData
+import collections
+import types
+#import sys
+#import ctypes
+
+class RecursiveObjectPoolManager(object):
+
+ def __init__(self):
+ self._pools = {} # 存储各类的对象池 {class: pool}
+ # 使用对象ID作为键的映射:{id(obj): obj_class}
+ self._obj_id_to_pool = {}
+ self._releasing = set() # 正在释放的对象ID集合
+
+ def create_pool(self, obj_class, max_size=10):
+ """为指定类创建对象池
+ :param obj_class: 要管理的对象类
+ :param max_size: 对象池最大容量
+ """
+ if obj_class in self._pools:
+ GameWorld.Log("Pool for %s already exists" % obj_class.__name__)
+ return
+ GameWorld.Log("create_pool %s, max_size=%s" % ( obj_class.__name__, max_size))
+
+ self._pools[obj_class] = {
+ 'max_size': max_size,
+ 'free_list': [], # 空闲对象列表
+ 'active_list': [], # 使用中对象列表
+ 'created_count': 0 # 已创建对象计数
+ }
+ return self
+
+ def acquire(self, obj_class, *args, **kwargs):
+ """获取对象并记录其所属池"""
+ if obj_class not in self._pools:
+ # 如果池不存在,自动创建大小为0的无限制池
+ self.create_pool(obj_class, 0)
+
+ pool = self._pools[obj_class]
+
+ if pool['free_list']:
+ # 复用空闲对象
+ obj = pool['free_list'].pop()
+ # 重新初始化对象
+ obj.__init__(*args, **kwargs)
+ else:
+ # 创建新对象
+ if pool['max_size'] <= 0 or pool['created_count'] < pool['max_size']:
+ obj = obj_class(*args, **kwargs)
+ pool['created_count'] += 1
+ # 记录对象到池的映射
+ obj_id = id(obj)
+ self._obj_id_to_pool[obj_id] = obj_class
+ else:
+ GameWorld.ErrLog("%s pool exhausted" % obj_class.__name__)
+ return None # 返回None表示获取失败
+
+ pool['active_list'].append(obj)
+ return obj
+
+ def release(self, obj):
+ """释放对象并递归释放其嵌套对象池对象"""
+ obj_id = id(obj)
+
+ # 检查是否正在递归释放中
+ if obj_id in self._releasing:
+ return
+
+ # 只处理对象池管理的对象
+ if obj_id not in self._obj_id_to_pool:
+ return
+
+ # 标记为正在释放
+ self._releasing.add(obj_id)
+ visited = set([obj_id]) # 初始化已访问集合
+
+ try:
+ # 1. 递归释放嵌套对象池对象
+ self._recursive_release(obj, visited)
+ # 2. 释放当前对象
+ self._return_to_pool(obj)
+ finally:
+ # 移除释放标记
+ self._releasing.discard(obj_id)
+
+ def _recursive_release(self, obj, visited):
+ """递归释放嵌套对象池对象(深度优先)"""
+ # 获取对象的所有引用(不包含基础类型)
+ for ref in self._get_references(obj):
+ try:
+ ref_id = id(ref)
+ except TypeError:
+ # 如果对象不可哈希,跳过
+ continue
+
+ if ref_id in visited:
+ continue
+ visited.add(ref_id)
+
+ # 只处理对象池管理的对象
+ if ref_id in self._obj_id_to_pool:
+ # 先递归释放嵌套对象
+ self._recursive_release(ref, visited)
+ # 再释放当前引用对象
+ self._return_to_pool(ref)
+ else:
+ # 对于非对象池管理的对象,继续递归查找其中的对象池对象
+ self._recursive_release(ref, visited)
+
+ def _get_references(self, obj):
+ """安全获取对象的所有直接引用,支持复杂数据结构"""
+ refs = []
+ obj_type = type(obj)
+
+ # 处理自定义对象的属性
+ try:
+ # 首先尝试__dict__属性
+ if hasattr(obj, '__dict__'):
+ for attr in dir(obj):
+ if attr.startswith('__'):
+ continue
+
+ try:
+ attr_value = getattr(obj, attr)
+ except Exception:
+ continue
+
+ # 过滤基础类型
+ if not self._is_basic_type(attr_value):
+ refs.append(attr_value)
+ except Exception:
+ pass
+
+ # 处理常见容器类型
+ if obj_type in (list, tuple, set, collections.deque):
+ for item in obj:
+ if not self._is_basic_type(item):
+ refs.append(item)
+ elif obj_type is dict:
+ for key, value in obj.iteritems():
+ if not self._is_basic_type(key):
+ refs.append(key)
+ if not self._is_basic_type(value):
+ refs.append(value)
+
+ # 处理特殊属性(如__slots__定义的对象)
+ try:
+ if hasattr(obj, '__slots__'):
+ for slot_name in obj.__slots__:
+ if hasattr(obj, slot_name):
+ slot_value = getattr(obj, slot_name)
+ if not self._is_basic_type(slot_value):
+ refs.append(slot_value)
+ except Exception:
+ pass
+
+ return refs
+
+ def _is_basic_type(self, value):
+ """判断值是否为基本类型,不需要递归处理"""
+ if value is None:
+ return True
+ if isinstance(value, (int, long, float, bool, str, unicode)):
+ return True
+ if isinstance(value, (types.FunctionType, types.MethodType, types.ModuleType)):
+ return True
+ if isinstance(value, (types.BuiltinFunctionType, type)):
+ return True
+ return False
+
+ def _return_to_pool(self, obj):
+ """将对象归还到其所属池"""
+ obj_id = id(obj)
+
+ # 获取对象所属类
+ if obj_id not in self._obj_id_to_pool:
+ return # 如果不在池中,忽略
+
+ obj_class = self._obj_id_to_pool[obj_id]
+
+ if obj_class not in self._pools:
+ return # 如果池不存在,忽略
+
+ pool = self._pools[obj_class]
+
+ # 确保对象在活跃列表中
+ if obj in pool['active_list']:
+ # 从活跃列表移除
+ try:
+ pool['active_list'].remove(obj)
+ except ValueError:
+ # 如果对象不在列表中,忽略
+ return
+
+ # 执行对象清理方法
+ #if hasattr(obj, 'cleanup'):
+ # try:
+ # obj.cleanup()
+ # except Exception:
+ # pass
+
+ # 添加到空闲列表
+ pool['free_list'].append(obj)
+ else:
+ # 如果在空闲列表中,跳过
+ pass
+
+ def destroy_pool(self, obj_class):
+ """销毁指定类的对象池"""
+ if obj_class not in self._pools:
+ return
+
+ pool = self._pools[obj_class]
+
+ # 清理所有对象
+ for obj in list(pool['free_list'] + pool['active_list']):
+ # 清理对象属性
+ #if hasattr(obj, 'cleanup'):
+ # try:
+ # obj.cleanup()
+ # except Exception:
+ # pass
+
+ # 从映射中移除
+ obj_id = id(obj)
+ if obj_id in self._obj_id_to_pool:
+ del self._obj_id_to_pool[obj_id]
+
+ del self._pools[obj_class]
+
+ def pool_status(self):
+ """输出所有对象池的状态信息"""
+ statusList = []
+ max_name_len = 0
+ max_created_len = 0
+ max_free_len = 0
+ max_active_len = 0
+
+ # 收集状态并计算最大长度
+ for obj_class, pool in self._pools.items():
+ # 获取类名
+ class_name = getattr(obj_class, '__name__', str(obj_class))
+ created = pool['created_count']
+ free = len(pool['free_list'])
+ active = len(pool['active_list'])
+
+ statusList.append({
+ 'obj_class': class_name,
+ 'created': created,
+ 'free': free,
+ 'active': active
+ })
+
+ # 计算最大长度
+ max_name_len = max(max_name_len, len(class_name))
+ max_created_len = max(max_created_len, len(str(created)))
+ max_free_len = max(max_free_len, len(str(free)))
+ max_active_len = max(max_active_len, len(str(active)))
+
+ # 添加表头长度
+ max_name_len = max(max_name_len, 8) # "对象池名称"的长度
+ max_created_len = max(max_created_len, 4) # "总数"的长度
+ max_free_len = max(max_free_len, 4) # "空闲"的长度
+ max_active_len = max(max_active_len, 4) # "活跃"的长度
+
+ # 按活跃对象数量排序
+ statusList.sort(key=lambda s: (s['created'], s['active']), reverse=True)
+
+ # 创建格式字符串
+ header_format = "| {:<{name_width}} | {:>{created_width}} | {:>{free_width}} | {:>{active_width}} |"
+ row_format = "| {:<{name_width}} | {:>{created_width}} | {:>{free_width}} | {:>{active_width}} |"
+
+ # 输出表头
+ GameWorld.Log("----- 对象池状态 -----")
+ GameWorld.Log(header_format.format(
+ "对象池名称", "总数", "空闲", "活跃",
+ name_width=max_name_len,
+ created_width=max_created_len,
+ free_width=max_free_len,
+ active_width=max_active_len
+ ))
+
+ # 输出分隔线
+ separator = "+-{}-+-{}-+-{}-+-{}-+".format(
+ "-" * max_name_len,
+ "-" * max_created_len,
+ "-" * max_free_len,
+ "-" * max_active_len
+ )
+ GameWorld.Log(separator)
+
+ # 输出数据行
+ for s in statusList:
+ GameWorld.Log(row_format.format(
+ s['obj_class'], s['created'], s['free'], s['active'],
+ name_width=max_name_len,
+ created_width=max_created_len,
+ free_width=max_free_len,
+ active_width=max_active_len
+ ))
+
+ return
+
+def GetPoolMgr():
+ """获取指定类创建对象池"""
+ poolMgr = PyGameData.g_objPoolMgr
+ if not poolMgr:
+ poolMgr = RecursiveObjectPoolManager()
+ PyGameData.g_objPoolMgr = poolMgr
+ return poolMgr
+
+def OnMinute():
+ """每分钟执行,输出对象池状态"""
+ GetPoolMgr().pool_status()
+ return
+
+## 使用示例
+#if __name__ == "__main__":
+#
+# # 定义一个嵌套的Structure类
+# class SubStructure(ctypes.Structure):
+# _fields_ = [("z", ctypes.c_int)]
+#
+# def __init__(self, name):
+# self.name = name
+# print "初始化SubStructure: name=%s" % (self.name)
+# return
+#
+# def cleanup(self):
+# """清理方法"""
+# print "清理SubStructure: name=%s" % (self.name)
+# self.name = None
+#
+# # 定义一个继承自Structure的类
+# class MyStructure(ctypes.Structure):
+# _fields_ = [("x", ctypes.c_int), ("y", ctypes.c_int)]
+#
+# def __init__(self, name):
+# self.name = name
+# # 嵌套的Structure对象
+# self.sub = GetPoolMgr().acquire(SubStructure, "%s_sub" % name)
+# print "初始化MyStructure: name=%s" % (self.name)
+# return
+#
+# def cleanup(self):
+# """清理方法"""
+# print "清理MyStructure: name=%s" % (self.name)
+# self.name = None
+# # 不需要手动释放sub,递归释放会处理
+# self.sub = None
+#
+# class ClassE():
+#
+# def __init__(self, name):
+# self.name = name
+# print "初始化对象 ClassE: name=%s" % (self.name)
+# self.ed1 = GetPoolMgr().acquire(ClassD, "%s_ed_1" % name)
+# return
+#
+# class ClassD():
+#
+# def __init__(self, name):
+# self.name = name
+# print "初始化对象 ClassD: name=%s" % (self.name)
+# return
+#
+# def cleanup(self):
+# """清理方法"""
+# print "清理ClassD: name=%s" % (self.name)
+# self.name = None
+#
+# class ClassC():
+#
+# def __init__(self, name, bb):
+# self.name = name
+# print "初始化对象 ClassC: name=%s" % (self.name)
+# self.bb = bb
+# self.cd1 = GetPoolMgr().acquire(ClassD, "%s_cd_1" % name)
+# self.cd2 = GetPoolMgr().acquire(ClassD, "%s_cd_2" % name)
+# return
+#
+# class ClassB():
+#
+# def __init__(self, name):
+# self.name = name
+# print "初始化对象 ClassB: name=%s" % (self.name)
+# bc1 = GetPoolMgr().acquire(ClassC, "%s_c_1" % name, self)
+# bc2 = GetPoolMgr().acquire(ClassC, "%s_c_2" % name, self)
+# self.cList = [bc1, bc2]
+# self.dDict = {1:GetPoolMgr().acquire(ClassD, "%s_d_1" % name), GetPoolMgr().acquire(ClassD, "%s_d_2" % name):2, "bc1":bc1, "bc2":bc2}
+# return
+#
+# def do(self, doStr):
+# print "ClassB.do name=%s, %s" % (self.name, doStr)
+# return
+#
+# class ClassA():
+#
+# def __init__(self, objID, name):
+# self.objID = objID
+# self.name = name
+# self.b = GetPoolMgr().acquire(ClassB, "%s_b" % name)
+# self.e = ClassE("%s_e" % name)
+# self.struct = GetPoolMgr().acquire(MyStructure, "%s_struct" % name) # Structure对象
+# self.dDict = {1:GetPoolMgr().acquire(ClassD, "%s_d_1" % name), GetPoolMgr().acquire(ClassD, "%s_d_2" % name):2}
+# print "初始化对象 ClassA: objID=%s,name=%s" % (self.objID, self.name)
+#
+# def do(self, doStr):
+# print "ClassA.do objID=%s,name=%s, %s" % (self.objID, self.name, doStr)
+# return
+#
+# def cleanup(self):
+# """清理方法"""
+# print "清理ClassA: objID=%s,name=%s" % (self.objID, self.name)
+# self.b = None
+# self.e = None
+# self.struct = None
+# self.dDict = None
+# self.name = None
+# self.objID = None
+#
+#
+# # 创建对象池管理器
+# poolMgr = GetPoolMgr()
+#
+# # 为所有类创建对象池,max_size=0 表示无限制
+# poolMgr.create_pool(ClassA, max_size=0)
+# poolMgr.create_pool(ClassB, max_size=0)
+# poolMgr.create_pool(ClassC, max_size=0)
+# poolMgr.create_pool(ClassD, max_size=0)
+# poolMgr.create_pool(MyStructure, max_size=0)
+# poolMgr.create_pool(SubStructure, max_size=0) # 嵌套的Structure类
+#
+# # 创建测试对象
+# a1 = poolMgr.acquire(ClassA, 1000, "hanmeimei")
+# if a1 is None:
+# GameWorld.ErrLog("Failed to acquire ClassA instance for hanmeimei")
+# else:
+# a1.do("hello 1ilei")
+#
+# a2 = poolMgr.acquire(ClassA, 1001, "lilei")
+# if a2 is None:
+# GameWorld.ErrLog("Failed to acquire ClassA instance for lilei")
+# else:
+# a2.do("hello hanmeimei")
+#
+# # 输出状态
+# print("\n释放前状态")
+# poolMgr.pool_status()
+#
+# # 释放对象
+# if a1:
+# poolMgr.release(a1)
+# if a2:
+# poolMgr.release(a2)
+#
+# # 输出状态
+# print("\n释放后状态")
+# poolMgr.pool_status()
+#
+# # 再次获取应复用对象
+# a3 = poolMgr.acquire(ClassA, 1002, "lihua")
+# if a3 is None:
+# GameWorld.ErrLog("Failed to acquire ClassA instance for lihua")
+# else:
+# a3.do("fuck you")
+#
+# # 输出状态
+# print("\n再次获取后状态")
+# poolMgr.pool_status()
+#
+# # 清理
+# if a3:
+# poolMgr.release(a3)
+# poolMgr.destroy_pool(ClassA)
+# poolMgr.destroy_pool(ClassB)
+# poolMgr.destroy_pool(ClassC)
+# poolMgr.destroy_pool(ClassD)
+# poolMgr.destroy_pool(MyStructure)
+# poolMgr.destroy_pool(SubStructure)
\ No newline at end of file
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
index b35b8c3..3ee73aa 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -578,7 +578,7 @@
# @return 返回值无意义
def ClearPyPlayerAction(curPlayer):
#清除py自定义状态
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_PyPlayerAction, 0)
+ NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_PyPlayerAction, 0)
return
#---------------------------------------------------------------------
@@ -2837,10 +2837,25 @@
#轮回殿
PlayerActLunhuidian.AddLunhuidianValue(curPlayer, PlayerActLunhuidian.AwardType_PayMoney, type_Price, price)
if type_Price == ShareDefine.TYPE_Price_Xiantao:
+ # 累加未结算战锤 - 经验
unXiantaoCntExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntExp)
NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntExp, unXiantaoCntExp + price)
+ # 累加未结算战锤 - 装备
unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip)
NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntEquip, unXiantaoCntEquip + price)
+ # 累加未结算战锤 - 战利品
+ chapterID = GetMainLevelNowInfo(curPlayer)[0]
+ chapterIpyData = IpyGameDataPY.GetIpyGameData("MainChapter", chapterID)
+ if chapterIpyData:
+ DailyBootyUpperList = chapterIpyData.GetDailyBootyUpperList()
+ for itemID, upperCnt in DailyBootyUpperList:
+ if upperCnt <= 0:
+ continue
+ if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BootyDropToday % itemID) >= upperCnt:
+ continue
+ unXiantaoCntBooty = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntBooty % itemID)
+ NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntBooty % itemID, unXiantaoCntBooty + price)
+
PlayerPrestigeSys.AddRealmTaskValue(curPlayer, PlayerPrestigeSys.RealmTaskType_UseXiantao, price)
unitPrice = price if quantity == 1 else int(math.ceil(price * 1.0 / quantity)) # 单价
#reason_name = "Unknown" if not costType else costType
@@ -3476,7 +3491,8 @@
# 杀怪
if expViewType == ShareDefine.Def_ViewExpType_KillNPC:
- exp_rate = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_TotalExpRate)
+ #exp_rate = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_TotalExpRate)
+ exp_rate = 10000
elif expViewType in [ShareDefine.Def_ViewExpType_GameEvent, ShareDefine.Def_ViewExpType_Sit]:
exp_rate = curPlayer.GetGameEventExpRate()
#exp_rate += GetFamilySitExpPer(curPlayer)
@@ -4965,12 +4981,6 @@
insidePerAttrDict = {}
customAttrDict = {}
return attrList, insidePerAttrDict, customAttrDict
-
-def GetLordAttr(curPlayer):
- ## 获取主公属性汇总
- lordAttrDict = {"Atk":curPlayer.GetMaxAtk(), "Def":curPlayer.GetDef(), "MaxHP":GameObj.GetMaxHP(curPlayer),
- "Hit":curPlayer.GetHit(), "Miss":curPlayer.GetMiss()}
- return lordAttrDict
#-------------------------------------------------------------------------------
## 设置玩家字典值, 存库
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py
index e51d59f..cbe7cb0 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py
@@ -30,7 +30,7 @@
import time
class LineupHero():
- ## 阵容战斗武将,注意:同一个武将在不同阵容中可能属性不一样
+ ## 阵容武将,注意:同一个武将在不同阵容中可能属性不一样
def __init__(self):
self.Clear()
@@ -39,6 +39,7 @@
def Clear(self):
self.itemIndex = 0
self.heroID = 0
+ self.skinID = 0
self.posNum = 0
self.heroBatAttrDict = {} # 武将的最终战斗属性字典, {attrID:value, ...}
self.heroSkillIDList = [] # 武将拥有的技能ID列表 [skillID, ...]
@@ -153,7 +154,7 @@
return
def OnClear(self):
- self.mainFight.clear()
+ self.mainFight.turnFight.clearFight()
return
def SetPlayer(self, curPlayer):
@@ -453,7 +454,15 @@
star = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroStar)
breakLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroBreakLV)
awakeLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroAwakeLV)
+ skinIndex = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroSkin)
+ skinID = 0
+ skinIDList = heroIpyData.GetSkinIDList()
+ if skinIndex < 0 or skinIndex >= len(skinIDList):
+ skinID = skinIDList[skinIndex]
+ elif skinIDList:
+ skinID = skinIDList[0]
+
InitAddPer += qualityIpyData.GetInitAddPer()
LVAddPer += qualityIpyData.GetLVAddPer() * heroLV
BreakLVAddPer += qualityIpyData.GetBreakLVAddPer() * breakLV
@@ -465,6 +474,7 @@
lineupHero.itemIndex = itemIndex
lineupHero.posNum = posNum
lineupHero.heroID = heroID
+ lineupHero.skinID = skinID
lineupHero.heroBatAttrDict = {}
lineupHero.heroSkillIDList = []
lineupHero.fightPower = 0
@@ -695,7 +705,7 @@
GameWorld.DebugLog(" fightPower=%s,heroSkillIDList=%s" % (fightPower, lineupHero.heroSkillIDList))
skillTypeIDDict = {}
for skillID in lineupHero.heroSkillIDList:
- skillData = GameWorld.GetGameData().GetSkillBySkillID(skillID)
+ skillData = IpyGameDataPY.GetIpyGameData("Skill", skillID)
if not skillData:
continue
skillTypeID = skillData.GetSkillTypeID()
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
index e22d418..862a17a 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -24,6 +24,9 @@
g_serverClosing = 0 # 是否关服中 0-非关服中;1-关服中;2-关服结束
g_closeSaveDataOK = False # 关服数据入库是否成功
+g_objPoolMgr = None # 对象池管理器
+g_batObjMgr = None # 战斗对象管理
+
g_pyGameDataManager = None
g_dbPlayerIDMap = {} # 本服DBPlayer玩家表ID映射关系 {playerID:accID, ...}
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py
index a835c35..6276416 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py
@@ -1284,13 +1284,13 @@
elif curObjType == IPY_GameWorld.gotNPC:
AttackCommon.NPCAddObjInHurtList(attackerOwner, curObj, curObjHP_BeforeAttack, lostValue)
- TurnAttack.AddTurnObjHurtValue(buffOwner, curObj, hurtType, lostValue, lostHP, curSkill)
+ #TurnAttack.AddTurnObjHurtValue(buffOwner, curObj, lostValue, lostHP, curSkill)
#统一调用攻击结束动作
if isDoAttackResult:
BaseAttack.DoLogic_AttackResult(buffOwner, curObj, None, tick)
- TurnAttack.OnTurnfightAttackResult(buffOwner, curObj, curSkill)
+ #TurnAttack.OnTurnfightAttackResult(buffOwner, curObj, curSkill)
return lostHP
## 检查增加淬毒buff
@@ -1852,12 +1852,16 @@
def isAngerSkill(curSkill):
## 是否怒气技能
- return curSkill and curSkill.GetXP() > 0
+ return curSkill and curSkill.GetFuncType() == ChConfig.Def_SkillFuncType_AngerSkill
def isTurnNormalSkill(curSkill):
## 是否回合普攻技能,区别与无技能的普通A一下,该普攻同样可以有各种技能效果,只是他属于普攻
return curSkill and curSkill.GetFuncType() == ChConfig.Def_SkillFuncType_TurnNormaSkill
+def isAtkbackSkill(curSkill):
+ ## 是否反击技能
+ return curSkill and curSkill.GetFuncType() == ChConfig.Def_SkillFuncType_AtkbackSkill
+
## 检查技能是否为被动技能, 用于控制不可释放技能
def isPassiveSkill(curSkill):
return curSkill.GetSkillType() in [ChConfig.Def_SkillType_Passive,
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PySkillManager.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PySkillManager.py
deleted file mode 100644
index 39225ed..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PySkillManager.py
+++ /dev/null
@@ -1,236 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#
-#
-##@package PySkillManager
-# @todo: 用于战斗模块所需接口,学习技能等其他所用接口可不开放
-# 支持临时改变数据以便战斗计算等其他效果
-# @author: Alee
-# @date: 2013-10-31 14:45
-# @version 1.1
-#
-# 修改时间 修改人 修改内容
-# @change: "2016-11-16 15:30" hxp 增加减少buff持续时间
-#
-#---------------------------------------------------------------------
-#"""Version = 2016-11-16 15:30"""
-#---------------------------------------------------------------------
-#导入
-
-# python 模拟技能效果结构
-class PySkillEffect():
-
- def __init__(self, effObj):
- self.effectID = effObj.GetEffectID()
-
- self.effectValueList = []
- for i in xrange(effObj.GetEffectValueCount()):
- self.effectValueList.append(effObj.GetEffectValue(i))
-
- return
-
- def Clear(self):
- self.effectID = 0
- self.effectValueList = []
-
- def GetEffectID(self):
- return self.effectID
-
- def GetEffectValue(self, index):
- return self.effectValueList[index]
-
- def GetEffectValueCount(self):
- return len(self.effectValueList)
-
- def SetEffectValue(self, index, value):
- self.effectValueList[index] = value
-
- def AddEffectValue(self, index, value):
- self.effectValueList[index] += value
-
-
-# python 模拟技能结构
-class PySkillData():
-
- def __init__(self):
- return
-
- def CopySkillData(self, skillData):
- self.Clear()
-
- self.effObjList = []
- for i in xrange(skillData.GetEffectCount()):
- self.effObjList.append(PySkillEffect(skillData.GetEffect(i)))
-
- self.skillID = skillData.GetSkillID()
- self.skillName = skillData.GetSkillName()
- self.skillTypeID = skillData.GetSkillTypeID()
- self.skillLV = skillData.GetSkillLV()
- self.skillMaxLV = skillData.GetSkillMaxLV()
- self.useType = skillData.GetUseType()
-
- self.funcType = skillData.GetFuncType()
-
- self.castTime = skillData.GetCastTime()
- self.skillType = skillData.GetSkillType()
- self.continueUse = skillData.GetContinueUse()
- self.atkType = skillData.GetAtkType()
- self.atkRadius = skillData.GetAtkRadius()
- self.tag = skillData.GetTag()
- self.atkDist = skillData.GetAtkDist()
- self.coolDownTime = skillData.GetCoolDownTime()
- self.mp = skillData.GetMP()
- self.hp = skillData.GetHP()
- self.xp = skillData.GetXP()
- self.useItemID = skillData.GetUseItemID()
- self.useItemCnt = skillData.GetUseItemCount()
- self.skillAngry = skillData.GetSkillAngry()
- self.skillEnhance1 = skillData.GetSkillEnhance1()
- self.skillEnhance2 = skillData.GetSkillEnhance2()
- self.happenRate = skillData.GetHappenRate()
- self.lastTime = skillData.GetLastTime()
- self.canRepeatTime = skillData.GetCanRepeatTime()
- self.commonCD = skillData.GetCommonCD()
- self.hurtType = skillData.GetHurtType()
- self.stiffTime = skillData.GetStiffTime()
- self.clientActionLimit = skillData.GetClientActionLimit()
- self.serverActionLimit = skillData.GetServerActionLimit()
- self.clientSkillSeriesLimit = skillData.GetClientSkillSeriesLimit()
- self.serverSkillSeriesLimit = skillData.GetServerSkillSeriesLimit()
- self.skillOfSeries = skillData.GetSkillOfSeries()
- self.exAttr1 = skillData.GetExAttr1()
- self.exAttr2 = skillData.GetExAttr2()
- self.exAttr3 = skillData.GetExAttr3()
- self.exAttr4 = skillData.GetExAttr4()
- self.exAttr5 = skillData.GetExAttr5()
-
- #非同步属性
- self.buffValueEffDict = {}
- return
-
-
- def Clear(self):
- self.effObjList = []
- self.skillID = 0
- self.skillName = 0
- self.skillTypeID = 0
- self.skillLV = 0
- self.skillMaxLV = 0
- self.useType = 0
- self.weaponTypeList = []
- self.castTime = 0
- self.skillType = 0
- self.continueUse = 0
- self.atkType = 0
- self.atkRadius = 0
- self.tag = 0
- self.atkDist = 0
- self.coolDownTime = 0
- self.mp = 0
- self.hp = 0
- self.xp = 0
- self.useItemID = 0
- self.useItemCnt = 0
- self.skillAngry = 0
- self.skillEnhance1 = 0
- self.skillEnhance2 = 0
- self.happenRate = 0
- self.lastTime = 0
- self.canRepeatTime = 0
- self.commonCD = 0
- self.hurtType = 0
- self.stiffTime = 0
- self.clientActionLimit = 0
- self.serverActionLimit = 0
- self.clientSkillSeriesLimit = 0
- self.serverSkillSeriesLimit = 0
- self.skillOfSeries = 0
- self.exAttr1 = 0
- self.exAttr2 = 0
- self.exAttr3 = 0
- self.exAttr4 = 0
- self.exAttr5 = 0
-
- #非同步属性
- self.buffValueEffDict = {}
- self.buffValue = {}
- return
-
- def GetEffect(self, index): return self.effObjList[index]
- def GetEffectCount(self): return len(self.effObjList)
- def GetSkillID(self): return self.skillID
- def GetSkillName(self): return self.skillID
- def GetSkillTypeID(self): return self.skillTypeID
- def GetSkillLV(self): return self.skillLV
- def GetSkillMaxLV(self): return self.skillMaxLV
- def GetUseType(self): return self.useType
- def GetFuncType(self, index): return self.funcType
- def GetCastTime(self): return self.castTime
- def GetSkillType(self): return self.skillType
- def GetContinueUse(self): return self.continueUse
- def GetAtkType(self): return self.atkType
- def GetAtkRadius(self): return self.atkRadius
- def GetTag(self): return self.tag
- def GetAtkDist(self): return self.atkDist
- def GetCoolDownTime(self): return self.coolDownTime
- def GetMP(self): return self.mp
- def GetHP(self): return self.hp
- def GetXP(self): return self.xp
- def GetUseItemID(self): return self.useItemID
- def GetUseItemCount(self): return self.useItemCnt
- def GetSkillAngry(self): return self.skillAngry
- def GetSkillEnhance1(self): return self.skillEnhance1
- def GetSkillEnhance2(self): return self.skillEnhance2
- def GetHappenRate(self): return self.happenRate
- def GetLastTime(self): return self.lastTime
- def GetCanRepeatTime(self): return self.canRepeatTime
- def GetCommonCD(self): return self.commonCD
- def GetHurtType(self): return self.hurtType
- def GetStiffTime(self): return self.stiffTime
- def GetClientActionLimit(self): return self.clientActionLimit
- def GetServerActionLimit(self): return self.serverActionLimit
- def GetClientSkillSeriesLimit(self): return self.clientSkillSeriesLimit
- def GetServerSkillSeriesLimit(self): return self.serverSkillSeriesLimit
- def GetSkillOfSeries(self): return self.skillOfSeries
- def GetExAttr1(self): return self.exAttr1
- def GetExAttr2(self): return self.exAttr2
- def GetExAttr3(self): return self.exAttr3
- def GetExAttr4(self): return self.exAttr4
- def GetExAttr5(self): return self.exAttr5
-
- #非同步接口--------------------------------------------------------------------
-
- def ReduceCoolDownTime(self, value):
- self.coolDownTime -= value
-
- def AddHappenRate(self, value):
- self.happenRate += value
-
- def AddLastTime(self, value):
- self.lastTime += value
-
- def DecLastTime(self, value):
- self.lastTime = max(0, self.lastTime - value)
-
- # BUFF类型的buffvalue处理
- def GetBuffValueByEffectID(self, effectID):
- return self.buffValueEffDict.get(effectID, 0)
-
- def AddBuffValueEff(self, effectID, value):
- self.buffValueEffDict[effectID] = value + self.buffValueEffDict.get(effectID, 0)
-
- # BUFF类型的buffvalue处理
- def GetBuffValueEx(self, index):
- return self.buffValue.get(index, 0)
-
- def AddBuffValueEx(self, index, value):
- self.buffValue[index] = value + self.buffValueEffDict.get(index, 0)
-
- def GetBuffValueDict(self):
- return self.buffValue
-#-------------------------------------------------------------------------------
-
-#全局,适用于单线程,慎用
-Py_SkillData = PySkillData() # 主动释放的技能
-Py_SkillDataTrigger = PySkillData() # 触发技能
-
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py
index 3452d8a..fd10975 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py
@@ -3494,7 +3494,7 @@
#调用攻击惩罚逻辑
BaseAttack.DoLogic_AttackResult(attacker, defender, None, tick)
- TurnAttack.OnTurnfightAttackResult(attacker, defender, curSkill)
+ #TurnAttack.OnTurnfightAttackResult(attacker, defender, curSkill)
return
#---------------------------------------------------------------------
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuff.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuff.py
new file mode 100644
index 0000000..7d4a172
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuff.py
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Skill.TurnBuff
+#
+# @todo:回合战斗buff
+# @author hxp
+# @date 2025-08-06
+# @version 1.0
+#
+# 详细描述: 回合战斗buff
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-08-06 18:30"""
+#-------------------------------------------------------------------------------
+
+import ChConfig
+import GameWorld
+import ChPyNetSendPack
+import ObjPool
+
+def OnAddBuff(turnFight, batObj, curSkill, buffOwner=None):
+ skillID = curSkill.GetSkillID()
+ enhanceBySkill = curSkill.GetEnhanceBySkill()
+ relatedSkillID = enhanceBySkill.GetSkillID() if enhanceBySkill else 0
+ curID = batObj.GetID()
+ ownerID = buffOwner.GetID() if buffOwner else curID
+ GameWorld.DebugLog("OnAddBuff: curID=%s,skillID=%s,ownerID=%s,relatedSkillID=%s" % (curID, skillID, ownerID, relatedSkillID))
+ #检查是否几率触发
+ if not enhanceBySkill:
+ rate = curSkill.GetHappenRate()
+ if rate and rate != ChConfig.Def_MaxRateValue and not GameWorld.CanHappen(rate, ChConfig.Def_MaxRateValue):
+ GameWorld.DebugLog(" 概率不触发buff!")
+ return
+
+ skillTypeID = curSkill.GetSkillTypeID()
+ # 先简单做下能加上即可
+ buffMgr = batObj.GetBuffManager()
+ buffIDList = buffMgr.FindBuffIDBySkillTypeID(skillTypeID)
+ if buffIDList:
+ GameWorld.DebugLog(" 已经存在该buff: skillTypeID=%s,buffIDList=%s" % (skillTypeID, buffIDList))
+ return True
+
+ buff = buffMgr.AddBuff(skillID)
+ if not buff:
+ GameWorld.DebugLog(" 添加buff失败! skillID=%s" % skillID)
+ return False
+ GameWorld.DebugLog(" AddBuffOK. buffID=%s" % buff.GetBuffID())
+ buff.SetOwnerID(ownerID)
+ buff.SetRemainTime(curSkill.GetLastTime())
+ #buff.SetLayer()
+ SyncBuffRefresh(turnFight, batObj, buff, relatedSkillID)
+ return True
+
+def SyncBuffRefresh(turnFight, curBatObj, curBuff, relatedSkillID=0):
+ clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCBuffRefresh)
+ clientPack.ObjID = curBatObj.GetID()
+ clientPack.BuffID = curBuff.GetBuffID()
+ clientPack.SkillID = curBuff.GetSkillID()
+ clientPack.RelatedSkillID = relatedSkillID
+ clientPack.LastTime = curBuff.GetRemainTime()
+ clientPack.Layer = curBuff.GetLayer()
+ clientPack.OwnerID = curBuff.GetOwnerID()
+ turnFight.addBatPack(clientPack)
+ return
+
+def SyncBuffDel(turnFight, curBatObj, buffID, relatedSkillID=0):
+ clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCBuffDel)
+ clientPack.ObjID = curBatObj.GetID()
+ clientPack.BuffID = buffID
+ clientPack.RelatedSkillID = relatedSkillID
+ turnFight.addBatPack(clientPack)
+ return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
new file mode 100644
index 0000000..7cbef56
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
@@ -0,0 +1,899 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Skill.TurnSkill
+#
+# @todo:回合战斗技能
+# @author hxp
+# @date 2025-08-06
+# @version 1.0
+#
+# 详细描述: 回合战斗技能
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-08-06 18:30"""
+#-------------------------------------------------------------------------------
+
+import ChConfig
+import GameWorld
+import BattleObj
+import SkillCommon
+import IpyGameDataPY
+import IPY_GameWorld
+import ChPyNetSendPack
+import PlayerControl
+import ShareDefine
+import TurnAttack
+import TurnBuff
+import ObjPool
+import FBLogic
+
+import random
+
+def GetPMType(batObj, useSkill):
+ ## 获取物法伤害类型
+ # GetHurtType 个位数用法改成 pvp pve标识,十位数-物攻法攻 IPY_GameWorld.ghtPhy = 1
+ #---技能攻击, 读表获取攻击类型---
+ ght = useSkill.GetHurtType() % 10
+ if ght == IPY_GameWorld.ghtMag: # 做配置兼容用,优先验证法伤,否则默认物伤
+ return IPY_GameWorld.ghtMag
+ return IPY_GameWorld.ghtPhy
+
+def IsIgnoreDef(useSkill):
+ ## 是否无视防御
+ return useSkill.GetHurtType() / 10 == 1 # 2为真伤,待扩展
+
+def OnUseSkill(turnFight, curBatObj, useSkill, tagObjList=None, batType=ChConfig.TurnBattleType_Normal, enhanceBySkill=None):
+ '''使用技能通用入口
+ @param useSkill: 使用的技能,注意并不一定是身上的技能,可能只是 SkillData 表数据
+ @param enhanceBySkill: 由哪个主技能额外触发的
+ @return: 是否成功
+ '''
+ if not useSkill:
+ return
+
+ skillID = useSkill.GetSkillID()
+ if not skillID:
+ return
+
+ #没有指定目标,则按技能自身的目标逻辑
+ if not tagObjList:
+ tagAim = useSkill.GetTagAim()
+ tagFriendly = useSkill.GetTagFriendly()
+ tagAffect = useSkill.GetTagAffect()
+ tagCount = useSkill.GetTagCount()
+ tagObjList = GetSkillTags(turnFight, curBatObj, tagAim, tagFriendly, tagAffect, tagCount)
+
+ enhanceBySkillID = enhanceBySkill.GetSkillID() if enhanceBySkill else 0
+ GameWorld.DebugLog("使用技能: curID=%s,skillID=%s,tagCnt=%s,batType=%s,enhanceBySkill=%s"
+ % (curBatObj.GetID(), skillID, len(tagObjList), batType, enhanceBySkillID))
+ if not tagObjList:
+ # 可扩展其他目标选择,如复活技能没有死亡单位时则使用另外的效果
+ return
+
+ # 以下为技能可以使用的处理,之后的逻辑默认技能使用成功
+
+ poolMgr = ObjPool.GetPoolMgr()
+ usePoolSkill = False
+ if isinstance(useSkill, IpyGameDataPY.IPY_Skill):
+ usePoolSkill = True
+ # 统一使用 BattleObj.PySkill
+ useSkill = poolMgr.acquire(BattleObj.PySkill, useSkill)
+
+ useSkill.SetTagObjList(tagObjList)
+ useSkill.SetBatType(batType)
+ useSkill.SetEnhanceBySkill(enhanceBySkill)
+ useSkill.ClearHurtObj()
+
+ curBatObj.ClearSkillTempAttr()
+ for tagObj in tagObjList:
+ tagObj.ClearSkillTempAttr()
+
+ objID = curBatObj.GetID()
+ useTag = ""
+ if not enhanceBySkill:
+ # 因为可能触发连击,所以标记需带上累计使用技能次数,确保唯一
+ useTag = "Skill_%s_%s_%s" % (objID, skillID, curBatObj.GetSkillUseCnt(skillID) + 1)
+ clientPack = poolMgr.acquire(ChPyNetSendPack.tagSCTurnFightTag)
+ clientPack.Tag = useTag
+ clientPack.Len = len(clientPack.Tag)
+ clientPack.Sign = 0
+ turnFight.addBatPack(clientPack)
+
+ #这个技能是Buff
+ if SkillCommon.IsBuff(useSkill):
+ __doAddBuff(turnFight, curBatObj, useSkill)
+ else:
+ __doUseSkill(turnFight, curBatObj, useSkill)
+
+ if useTag:
+ clientPack = poolMgr.acquire(ChPyNetSendPack.tagSCTurnFightTag)
+ clientPack.Tag = useTag
+ clientPack.Len = len(clientPack.Tag)
+ clientPack.Sign = 1
+ turnFight.addBatPack(clientPack)
+
+ # 最后重置、清空回收对象池
+ useSkill.SetTagObjList([])
+ useSkill.SetEnhanceBySkill(None) # 需重置,防止主技能被误回收
+ useSkill.ClearHurtObj()
+ if usePoolSkill:
+ poolMgr.release(useSkill)
+ return True
+
+def GetSkillTags(turnFight, curBatObj, tagAim, tagFriendly, tagAffect, tagCount):
+ ## 获取技能目标
+ curFaction = curBatObj.GetFaction()
+
+ # 自己,直接返回
+ if tagAim == ChConfig.SkillTagAim_Self:
+ return [curBatObj]
+
+ if tagFriendly:
+ tagFaction = curFaction
+ else:
+ tagFaction = ChConfig.Def_FactionB if curFaction == ChConfig.Def_FactionA else ChConfig.Def_FactionA
+
+ batObjMgr = BattleObj.GetBatObjMgr()
+ lineupNum = curBatObj.GetLineupNum()
+ posNum = curBatObj.GetPosNum()
+
+ batFaction = turnFight.getBatFaction(tagFaction)
+ if tagFaction == curFaction:
+ lineupNumList = [lineupNum] # 友方暂时仅限制自己阵容
+ else:
+ lineupNumList = [lineupNum] # 敌方优先对位阵容,再其他阵容
+ for tagNum in batFaction.lineupDict.keys():
+ if tagNum not in lineupNumList:
+ lineupNumList.append(tagNum)
+
+ aimObjList = [] # 先筛选出范围目标
+ for num in lineupNumList:
+ batLineup = batFaction.getBatlineup(num)
+
+ # 对位
+ if tagAim == ChConfig.SkillTagAim_Relative:
+ posNumList = [posNum] # 优先对位位置,再其他位置按顺序遍历
+ pNumList = batLineup.posObjIDDict.keys()
+ pNumList.sort()
+ for pNum in pNumList:
+ if pNum > 0 and pNum not in posNumList:
+ posNumList.append(pNum)
+ for pNum in posNumList:
+ if pNum not in batLineup.posObjIDDict:
+ continue
+ tagObjID = batLineup.posObjIDDict[pNum]
+ tagBatObj = batObjMgr.getBatObj(tagObjID)
+ if not __skillTagFilter(tagBatObj, tagAffect):
+ continue
+ aimObjList.append(tagBatObj) # 对位的默认只选1个
+ break
+
+ # 前排
+ elif tagAim == ChConfig.SkillTagAim_FrontRow:
+ # 优先前排,如果没有则后排亦是前排
+ for pNumList in [[1, 2, 3], [4, 5, 6]]:
+ hasObj = False
+ for pNum in pNumList:
+ if pNum not in batLineup.posObjIDDict:
+ continue
+ tagObjID = batLineup.posObjIDDict[pNum]
+ tagBatObj = batObjMgr.getBatObj(tagObjID)
+ if not __skillTagFilter(tagBatObj, tagAffect):
+ continue
+ hasObj = True
+ aimObjList.append(tagBatObj)
+ if hasObj:
+ break
+
+ # 后排
+ elif tagAim == ChConfig.SkillTagAim_BackRow:
+ # 优先后排,如果没有则前排亦是后排
+ for pNumList in [[4, 5, 6], [1, 2, 3]]:
+ hasObj = False
+ for pNum in pNumList:
+ if pNum not in batLineup.posObjIDDict:
+ continue
+ tagObjID = batLineup.posObjIDDict[pNum]
+ tagBatObj = batObjMgr.getBatObj(tagObjID)
+ if not __skillTagFilter(tagBatObj, tagAffect):
+ continue
+ hasObj = True
+ aimObjList.append(tagBatObj)
+ if hasObj:
+ break
+
+ # 竖排/纵排
+ elif tagAim == ChConfig.SkillTagAim_Vertical:
+ verticalNumList = [[1, 4], [2, 5], [3, 6]]
+ for pNumList in verticalNumList:
+ # 优先对位排
+ if posNum in pNumList:
+ verticalNumList.remove(pNumList)
+ verticalNumList.insert(0, pNumList)
+ break
+ for pNumList in verticalNumList:
+ hasObj = False
+ for pNum in pNumList:
+ if pNum not in batLineup.posObjIDDict:
+ continue
+ tagObjID = batLineup.posObjIDDict[pNum]
+ tagBatObj = batObjMgr.getBatObj(tagObjID)
+ if not __skillTagFilter(tagBatObj, tagAffect):
+ continue
+ hasObj = True
+ aimObjList.append(tagBatObj)
+ if hasObj:
+ break
+
+ # 其他,默认全部
+ else:
+ pNumList = batLineup.posObjIDDict.keys()
+ for pNum in pNumList:
+ if pNum <= 0:
+ continue
+ tagObjID = batLineup.posObjIDDict[pNum]
+ tagBatObj = batObjMgr.getBatObj(tagObjID)
+ if not __skillTagFilter(tagBatObj, tagAffect):
+ continue
+ aimObjList.append(tagBatObj)
+
+ # 目标细分
+ # 血量最低
+ if tagAffect == ChConfig.SkillTagAffect_HPLowest:
+ aimObjList.sort(key=lambda o:(o.GetHP()), reverse=False)
+ aimObjList = aimObjList[:tagCount]
+
+ # 血量最高
+ elif tagAffect == ChConfig.SkillTagAffect_HPHighest:
+ aimObjList.sort(key=lambda o:(o.GetHP()), reverse=True)
+ aimObjList = aimObjList[:tagCount]
+
+ else:
+ # 范围目标超过个数,则随机取
+ if tagCount and len(aimObjList) > tagCount:
+ random.shuffle(aimObjList)
+ aimObjList = aimObjList[:tagCount]
+
+ return aimObjList
+
+def __skillTagFilter(tagBatObj, tagAffect):
+ ## 技能目标过滤器
+ # @return: 是否允许添加该单位
+ if not tagBatObj:
+ return False
+ if tagAffect != ChConfig.SkillTagAffect_Death and tagBatObj.GetHP() <= 0:
+ return False
+ if tagAffect == ChConfig.SkillTagAffect_Death and tagBatObj.GetHP() > 0:
+ return False
+ if not tagBatObj.GetCanAttack():
+ return False
+ return True
+
+def __doAddBuff(turnFight, curBatObj, useSkill):
+ #执行添加buff
+
+ for tagBatObj in useSkill.GetTagObjList():
+ TurnBuff.OnAddBuff(turnFight, tagBatObj, useSkill, buffOwner=curBatObj)
+
+ DoAttackResult(turnFight, curBatObj, useSkill)
+ return
+
+def __doUseSkill(turnFight, curBatObj, useSkill):
+
+ atkType = useSkill.GetAtkType()
+ GameWorld.DebugLog("__doUseSkill: curID=%s,skillID=%s,atkType=%s" % (curBatObj.GetID(), useSkill.GetSkillID(), atkType))
+ # 通用攻击
+ if atkType == 1:
+ SkillModule_1(turnFight, curBatObj, useSkill)
+ return
+
+ # 治疗
+ if atkType == 2:
+ SkillModule_2(turnFight, curBatObj, useSkill)
+ return
+
+ # 复活
+ if atkType == 3:
+ return
+
+ # 多次攻击(锁目标多次伤害,非前端的多段飘血)
+ if atkType == 4:
+ return
+
+ # 弹射(多次攻击,切换目标)
+ if atkType == 5:
+ return
+
+ # 6 怒气增减偷
+ if atkType == 6:
+ SkillModule_6(turnFight, curBatObj, useSkill)
+ return
+
+ return
+
+def SkillModule_1(turnFight, curBatObj, useSkill):
+ ## 通用攻击,单攻、群攻
+
+ #执行攻击结果
+ for tagBatObj in useSkill.GetTagObjList():
+ __doSkillHurtHP(curBatObj, tagBatObj, useSkill)
+
+ DoAttackResult(turnFight, curBatObj, useSkill)
+ return
+
+def SkillModule_2(turnFight, curBatObj, useSkill):
+ ## 治疗
+
+ skillID = useSkill.GetSkillID()
+ for tagBatObj in useSkill.GetTagObjList():
+ cureHP = CalcCureHP(curBatObj, tagBatObj, useSkill, largeNum=True)
+ if cureHP <= 0:
+ continue
+
+ dHP = tagBatObj.GetHP()
+ dMapHP = tagBatObj.GetMaxHP()
+
+ remainHP = min(dHP + cureHP, dMapHP)
+ realCureHP = max(remainHP - dHP, 0)
+ tagBatObj.SetHP(remainHP)
+
+ dID = tagBatObj.GetID()
+ hurtObj = useSkill.AddHurtObj(dID)
+ hurtObj.AddHurtType(ChConfig.HurtTYpe_Recovery)
+ hurtObj.SetHurtHP(cureHP)
+ hurtObj.SetLostHP(realCureHP)
+ hurtObj.SetCurHP(tagBatObj.GetHP())
+ GameWorld.DebugLog(" 治疗: dID=%s,cureHP=%s,realCureHP=%s,%s/%s" % (dID, cureHP, realCureHP, tagBatObj.GetHP(), dMapHP))
+
+ TurnAttack.AddTurnObjCureHP(tagBatObj, curBatObj, cureHP, realCureHP, skillID)
+
+ DoAttackResult(turnFight, curBatObj, useSkill)
+ return
+
+def SkillModule_6(turnFight, curBatObj, useSkill):
+ ## 怒气增减偷
+
+ curID = curBatObj.GetID()
+ skillID = useSkill.GetSkillID()
+ enhanceBySkill = useSkill.GetEnhanceBySkill()
+ relatedSkillID = enhanceBySkill.GetSkillID() if enhanceBySkill else 0
+
+ effIDNum = useSkill.FindEffectID(ChConfig.Def_Skill_Effect_Anger)
+ angerPer = useSkill.GetEffectValue(effIDNum, 0) # 最大值的百分比,万分率
+ angerValue = useSkill.GetEffectValue(effIDNum, 1) # 固定值
+ calcType = useSkill.GetEffectValue(effIDNum, 2) # 计算方式(1增 2减 3偷)
+ xpMax = IpyGameDataPY.GetFuncCfg("AngerXP", 2)
+ calcValue = int(xpMax * angerPer / 10000.0 + angerValue)
+ attrID = ChConfig.AttrID_XP
+
+ GameWorld.DebugLog("怒气增减偷: curID=%s,calcValue=%s,skillID=%s,angerPer=%s,angerValue=%s,calcType=%s,relatedSkillID=%s"
+ % (curID, calcValue, skillID, angerPer, angerValue, calcType, relatedSkillID))
+ curStealTotal = 0
+ for tagBatObj in useSkill.GetTagObjList():
+
+ tagID = tagBatObj.GetID()
+ # 减
+ if calcType == 2:
+ diffType = 0
+ tagXP = tagBatObj.GetXP()
+ diffValue = min(tagXP, calcValue) # 取较小值,不足时剩多少减多少
+ updValue = tagXP - diffValue
+ tagBatObj.SetXP(updValue, False)
+ GameWorld.DebugLog(" 减怒气: tagID=%s,diffValue=%s,tagXP=%s,updXP=%s" % (tagID, diffValue, tagXP, updValue))
+ Sync_PropertyRefreshView(turnFight, tagBatObj, attrID, updValue, diffValue, diffType, skillID, relatedSkillID)
+
+ # 偷
+ elif calcType == 3:
+ diffType = 0
+ tagXP = tagBatObj.GetXP()
+ diffValue = min(tagXP, calcValue) # 取较小值,不足时剩多少减多少
+ updValue = tagXP - diffValue
+ tagBatObj.SetXP(updValue, False)
+ GameWorld.DebugLog(" 偷怒气: tagID=%s,diffValue=%s,tagXP=%s,updXP=%s" % (tagID, diffValue, tagXP, updValue))
+ Sync_PropertyRefreshView(turnFight, tagBatObj, attrID, updValue, diffValue, diffType, skillID, relatedSkillID)
+
+ curStealTotal += diffValue
+
+ # 其他默认加
+ else:
+ diffType = 1
+ tagXP = tagBatObj.GetXP()
+ diffValue = calcValue
+ updValue = tagXP + diffValue
+ tagBatObj.SetXP(updValue, False)
+ GameWorld.DebugLog(" 加怒气: tagID=%s,diffValue=%s,tagXP=%s,updXP=%s" % (tagID, diffValue, tagXP, updValue))
+ Sync_PropertyRefreshView(turnFight, tagBatObj, attrID, updValue, diffValue, diffType, skillID, relatedSkillID)
+
+ if curStealTotal > 0:
+ diffType = 1
+ curXP = curBatObj.GetXP()
+ diffValue = curStealTotal
+ updValue = curXP + diffValue
+ curBatObj.SetXP(updValue, False)
+ GameWorld.DebugLog(" 偷总怒气: curID=%s,curStealTotal=%s,curXP=%s,updXP=%s" % (curID, curStealTotal, curXP, updValue))
+ Sync_PropertyRefreshView(turnFight, curBatObj, attrID, updValue, diffValue, diffType, skillID, relatedSkillID)
+
+ DoAttackResult(turnFight, curBatObj, useSkill)
+ return
+
+def DoAttackResult(turnFight, curBatObj, useSkill):
+ '''执行攻击结果,技能、buff通用
+ @param curBatObj: 施法方或buff归属方
+ '''
+
+ if curBatObj:
+ # 反弹、吸血 的原因,需要统一处理后结算,可能导致HP为负值,修正为0
+ if curBatObj.GetHP() < 0:
+ curBatObj.SetHP(0)
+
+ skillID = useSkill.GetSkillID()
+ curBatObj.AddSkillUseCnt(skillID)
+
+ # 需先通知伤血 - 前端按顺序优先表现主技能内容,
+ enhanceBySkill = useSkill.GetEnhanceBySkill()
+ if not enhanceBySkill:
+ Sync_UseSkill(turnFight, curBatObj, useSkill)
+ __doCostZhanchui(turnFight, curBatObj, useSkill)
+ __doSkillUserAnger(turnFight, curBatObj, useSkill)
+
+ # 统计死亡
+ killObjIDList = [] # 击杀的目标ID列表
+ for tagObj in useSkill.GetTagObjList():
+ tagID = tagObj.GetID()
+ hurtObj = useSkill.GetHurtObj(tagID)
+ if hurtObj and not hurtObj.HaveHurtType(ChConfig.HurtTYpe_Recovery):
+ __doSkillHurtAnger(tagObj, hurtObj.GetLostHP(), useSkill)
+ if tagObj.GetHP() <= 0:
+ killObjIDList.append(tagID)
+ TurnAttack.SetObjKilled(turnFight, tagObj, curBatObj, useSkill)
+ if curBatObj.GetHP() <= 0:
+ TurnAttack.SetObjKilled(turnFight, curBatObj)
+
+ # 结算副本相关的攻击结果,仅主动发起玩家阵容武将触发
+ curPlayer = turnFight.curPlayer
+ if curPlayer and curBatObj.GetOwnerID() == curPlayer.GetPlayerID():
+ FBLogic.OnPlayerLineupAttackResult(curPlayer, curBatObj, killObjIDList, useSkill, turnFight.mapID, turnFight.funcLineID)
+
+ # 额外触发技能
+ __doUseEnhanceSkill(turnFight, curBatObj, useSkill)
+
+ # 循环触发被动,待扩展
+
+ # 最后处理反击 或 连击
+
+ return
+
+def __doCostZhanchui(turnFight, curBatObj, useSkill):
+
+ turnFight.mapID
+ if turnFight.mapID != ChConfig.Def_FBMapID_Main:
+ ## 仅主线战斗需要
+ return
+
+ curPlayer = turnFight.curPlayer
+ if not curPlayer:
+ return
+ # 仅主动发起玩家阵容武将释放技能需要消耗
+ if curBatObj.GetOwnerID() != curPlayer.GetPlayerID():
+ return
+
+ costZhanchui = 0
+ batType = useSkill.GetBatType()
+ if SkillCommon.isAngerSkill(useSkill):
+ costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 2)
+ elif batType == ChConfig.TurnBattleType_Combo:
+ costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 3)
+ elif batType == ChConfig.TurnBattleType_AtkBack:
+ costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 4)
+ elif SkillCommon.isTurnNormalSkill(useSkill):
+ costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 1)
+
+ if costZhanchui <= 0:
+ return
+
+ fightPoint = max(curPlayer.GetFightPoint(), 1) # 主线战斗消耗倍值,默认1
+ costZhanchuiTotal = costZhanchui * fightPoint
+ if not PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, costZhanchuiTotal, isNotify=False):
+ # 不足时,有多少扣多少
+ nowMoney = PlayerControl.GetMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao)
+ PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, min(nowMoney, costZhanchuiTotal), isNotify=False)
+
+ return
+
+def __doSkillUserAnger(turnFight, curBatObj, useSkill):
+ ## 技能释放者怒气相关
+ if SkillCommon.isAngerSkill(useSkill):
+ curBatObj.SetXP(0)
+ elif SkillCommon.isTurnNormalSkill(useSkill):
+ addXP = IpyGameDataPY.GetFuncCfg("AngerXP", 3)
+ AddTurnFightXP(curBatObj, addXP, "skillID:%s" % useSkill.GetSkillID())
+ return
+
+def __doSkillHurtAnger(batObj, lostHP, useSkill):
+ ## 结算受伤者怒气
+ if lostHP <= 0:
+ return
+ addXP = IpyGameDataPY.GetFuncCfg("AngerXP", 4)
+ if addXP <= 0:
+ return
+ AddTurnFightXP(batObj, addXP, "skillID:%s" % useSkill.GetSkillID())
+ return
+
+def AddTurnFightXP(gameObj, addXP, reason=""):
+ ## 回合战斗增加XP
+ if addXP <= 0 or not addXP:
+ #GameWorld.DebugLog(" 没有增加XP! curID=%s" % (gameObj.GetID()))
+ return
+ posNum = gameObj.GetPosNum()
+ if posNum <= 0:
+ #非主战单位不加
+ return
+ curXP = gameObj.GetXP()
+ updXP = curXP + addXP
+ gameObj.SetXP(updXP)
+ GameWorld.DebugLog(" 更新XP: curID=%s,curXP=%s,addXP=%s,updXP=%s,reason=%s" % (gameObj.GetID(), curXP, addXP, updXP, reason))
+ return
+
+def __doUseEnhanceSkill(turnFight, curBatObj, useSkill):
+ if useSkill.GetEnhanceBySkill():
+ GameWorld.DebugLog("自身为额外触发的技能不再触发额外技能! skillID=%s" % useSkill.GetSkillID())
+ return
+ enhanceSkillIDList = useSkill.GetEnhanceSkillList()
+ if not enhanceSkillIDList:
+ return
+ GameWorld.DebugLog("额外触发的技能! skillID=%s,enhanceSkillIDList=%s" % (useSkill.GetSkillID(), enhanceSkillIDList))
+ # 根据触发技能的特点决定是触发一次还是 触发多次
+ # 群体BUFF的请参考 IsPlayerUseSkill 客户端决定对象,一样可以实现同样效果
+ tagObjList = useSkill.GetTagObjList()
+ for enhanceSkillID in enhanceSkillIDList:
+ enhanceSkillData = IpyGameDataPY.GetIpyGameData("Skill", enhanceSkillID)
+ if not enhanceSkillData:
+ continue
+ # 继承主技能目标
+ if enhanceSkillData.GetTagAim() == ChConfig.SkillTagAim_MainSkill:
+ GameWorld.DebugLog(" 额外触发技能,继承主技能目标! enhanceSkillID=%s" % enhanceSkillID)
+ # 额外触发的技能直接在外层检查概率,如果都没有触发则不需要再处理
+ enhanceRate = enhanceSkillData.GetHappenRate()
+ enchanceTagObjList = []
+ for tagObj in tagObjList:
+ tagID = tagObj.GetID()
+ if tagObj.GetHP() <= 0:
+ GameWorld.DebugLog(" 已被击杀不触发: tagID=%s" % (tagID))
+ continue
+ hurtObj = useSkill.GetHurtObj(tagID)
+ if not hurtObj:
+ GameWorld.DebugLog(" 没有伤血不触发: tagID=%s" % (tagID))
+ continue
+ if hurtObj.HaveHurtType(ChConfig.HurtType_Miss):
+ GameWorld.DebugLog(" 闪避的对象不再触发技能: tagID=%s,enhanceSkillID=%s" % (tagID, enhanceSkillID))
+ continue
+ if enhanceRate and enhanceRate != ChConfig.Def_MaxRateValue and not GameWorld.CanHappen(enhanceRate, ChConfig.Def_MaxRateValue):
+ GameWorld.DebugLog(" 概率不触发: tagID=%s,enhanceRate=%s" % (tagID, enhanceRate))
+ continue
+
+ enchanceTagObjList.append(tagObj)
+
+ if enchanceTagObjList:
+ OnUseSkill(turnFight, curBatObj, enhanceSkillData, enchanceTagObjList, enhanceBySkill=useSkill)
+
+ continue
+
+ GameWorld.DebugLog(" 额外触发技能,重新锁定目标! enhanceSkillID=%s" % enhanceSkillID)
+ OnUseSkill(turnFight, curBatObj, enhanceSkillData, enhanceBySkill=useSkill)
+
+ return
+
+def __doSkillHurtHP(attacker, defObj, curSkill):
+ ## 执行技能伤血,只计算伤血,其他逻辑等技能同步后再处理
+ # @return: None - 没有执行成功,即忽略该目标
+
+ atkObj = attacker
+ atkID = atkObj.GetID()
+ defID = defObj.GetID()
+ hurtObj = curSkill.AddHurtObj(defID)
+
+ #检查是否几率触发
+ if not curSkill.GetEnhanceBySkill(): # 额外触发的技能概率在触发时判断
+ rate = curSkill.GetHappenRate()
+ if rate and rate != ChConfig.Def_MaxRateValue and not GameWorld.CanHappen(rate, ChConfig.Def_MaxRateValue):
+ #GameWorld.Log('检查是否几率触发 = %s失败 = %s'%(rate, useSkill.GetSkillName()))
+ #放这里,兼容群攻时如果该技能是有概率的,则每个目标单独判断
+ hurtObj.AddHurtType(ChConfig.HurtType_Fail)
+ hurtObj.SetCurHP(defObj.GetHP())
+ return hurtObj
+
+ atkEffIDNum = curSkill.FindEffectID(ChConfig.Def_Skill_Effect_Attack)
+ atkSkillValue = 0
+ atkSkillPer = curSkill.GetEffectValue(atkEffIDNum, 0)
+
+ dHP = defObj.GetHP() # 防守方当前血量
+ dMaxHP = defObj.GetMaxHP() # 防守方最大血量
+
+ zhansha = False # 斩杀特殊处理
+ # 斩杀
+ if zhansha:
+ pass
+
+ else:
+ hurtValue, hurtTypes = CalcHurtHP(atkObj, defObj, curSkill, atkSkillValue, atkSkillPer)
+
+ # 各种减伤 吸收盾处理
+ #hurtValue = CalcHurtHPWithBuff(atkObj, defObj, hurtValue, curSkill, tick)
+
+ #伤害结构体
+ hurtObj.SetHurtTypes(hurtTypes)
+ hurtObj.SetHurtHP(hurtValue)
+ remainHP = min(dMaxHP, max(0, dHP - hurtValue)) # 剩余血量
+
+ remainHP = int(remainHP) #防范
+ lostHP = dHP - remainHP # 实际掉血量
+ hurtObj.SetLostHP(lostHP)
+ hurtObj.SetCurHP(remainHP)
+ defObj.SetHP(remainHP)
+ GameWorld.DebugLog(" 伤血: atkID=%s,defID=%s,hurtValue=%s,lostHP=%s,%s/%s" % (atkID, defID, hurtValue, lostHP, defObj.GetHP(), defObj.GetMaxHP()))
+
+ #反弹伤害
+ CalcBounceHP(atkObj, defObj, hurtObj, curSkill)
+
+ #吸血
+ CalcSuckBlood(atkObj, defObj, hurtObj, curSkill)
+
+ TurnAttack.AddTurnObjHurtValue(atkObj, defObj, hurtValue, lostHP, curSkill)
+ return hurtObj
+
+def CalcHurtHP(atkObj, defObj, curSkill, atkSkillValue, atkSkillPer, **atkwargs):
+ '''计算伤害
+ '''
+ pmType = GetPMType(atkObj, curSkill)
+ ignoreDef = IsIgnoreDef(curSkill)
+
+ atkID = atkObj.GetID()
+ defID = defObj.GetID()
+
+ skillID = curSkill.GetSkillID()
+ isTurnNormalSkill = SkillCommon.isTurnNormalSkill(curSkill)
+ isAngerSkill = SkillCommon.isAngerSkill(curSkill)
+ isAtkbackSkill = SkillCommon.isAtkbackSkill(curSkill)
+
+ angerOverflow = 0 # 怒气溢出值
+
+ mustHit = False
+ if isAngerSkill:
+ mustHit = True
+ GameWorld.DebugLog(" XP必命中")
+ angerOverflow = max(atkObj.GetXP() - IpyGameDataPY.GetFuncCfg("AngerXP", 2), 0)
+
+ #命中公式 攻击方类型不同,公式不同
+ if not mustHit:
+ aMissRateDef = atkObj.GetAttrValue(ChConfig.AttrID_MissRateDef) #atkObj.GetHit() # 抗闪避率 - 命中
+ dMissRate = defObj.GetAttrValue(ChConfig.AttrID_MissRate) # 闪避率
+ missNum = defObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnMissNum)
+ missRate = eval(IpyGameDataPY.GetFuncCompileCfg("MissCfg", 1))
+ if GameWorld.CanHappen(missRate):
+ return 0, pow(2, ChConfig.HurtType_Miss)
+
+ hurtTypes = pow(2, ChConfig.HurtType_Normal)
+
+ isSuperHit = False # 是否暴击
+ if isSuperHit:
+ hurtTypes |= pow(2, ChConfig.HurtType_SuperHit)
+
+ isParry = False # 是否格挡
+ if isParry:
+ hurtTypes |= pow(2, ChConfig.HurtType_Parry)
+
+ if ignoreDef:
+ hurtTypes |= pow(2, ChConfig.HurtType_IgnoreDef)
+
+ #参与运算的数值
+ rand = random.random() #种子数 0~1
+
+ aAtk = atkObj.GetAttrValue(ChConfig.AttrID_Atk) # 攻击方最大攻击
+
+ dHP = defObj.GetHP()
+ dDef = 0 if ignoreDef else defObj.GetAttrValue(ChConfig.AttrID_Def) # 防守方防御力
+
+ aFinalDamPer = atkObj.GetAttrValue(ChConfig.AttrID_FinalDamPer) # 最终加成
+ dFinalDamPerDef = defObj.GetAttrValue(ChConfig.AttrID_FinalDamPerDef) # 最终减伤
+
+ aNormalSkillPer, dNormalSkillPerDef = 0, 0
+ if isTurnNormalSkill:
+ aNormalSkillPer = atkObj.GetAttrValue(ChConfig.AttrID_NormalSkillPer) # 普技增伤
+ dNormalSkillPerDef = defObj.GetAttrValue(ChConfig.AttrID_NormalSkillPerDef) # 普技减伤
+
+ aAngerSkillPer, dAngerSkillPerDef = 0, 0
+ if isAngerSkill:
+ aAngerSkillPer = atkObj.GetAttrValue(ChConfig.AttrID_AngerSkillPer) # 普技增伤
+ dAngerSkillPerDef = defObj.GetAttrValue(ChConfig.AttrID_AngerSkillPerDef) # 普技减伤
+
+ # 物法增减伤
+ if pmType == IPY_GameWorld.ghtMag: # 法伤
+ aPMDamPer = atkObj.GetAttrValue(ChConfig.AttrID_MagDamPer)
+ dPMDamPerDef = defObj.GetAttrValue(ChConfig.AttrID_MagDamPerDef)
+ else: # 物伤
+ aPMDamPer = atkObj.GetAttrValue(ChConfig.AttrID_PhyDamPer)
+ dPMDamPerDef = defObj.GetAttrValue(ChConfig.AttrID_PhyDamPerDef)
+
+ # 所有万分率参数统一除10000.0
+ atkSkillPer /= 10000.0
+ aNormalSkillPer /= 10000.0
+ dNormalSkillPerDef /= 10000.0
+ aAngerSkillPer /= 10000.0
+ dAngerSkillPerDef /= 10000.0
+ aPMDamPer /= 10000.0
+ dPMDamPerDef /= 10000.0
+ aFinalDamPer /= 10000.0
+ dFinalDamPerDef /= 10000.0
+
+
+ GameWorld.DebugLog("伤血计算: atkID=%s,defID=%s,skillID=%s,atkSkillPer=%s,aAtk=%s,dDef=%s,dHP=%s,hurtTypes=%s"
+ % (atkID, defID, skillID, atkSkillPer, aAtk, dDef, dHP, hurtTypes))
+
+ if "hurtFormulaKey" in atkwargs:
+ aBurnValue = atkwargs.get('burnValue', 0)
+ aBurnPer = atkwargs.get('burnPer', 0)
+ hurtFormulaKey = atkwargs.get('hurtFormulaKey', None)
+ hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("DOTFormula", 1))
+ elif isTurnNormalSkill:
+ hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("HurtFormula", 1))
+ GameWorld.DebugLog(" 普攻技能伤害=%s" % (hurtValue))
+ elif isAngerSkill:
+ hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("HurtFormula", 2))
+ GameWorld.DebugLog(" 怒气技能伤害=%s" % (hurtValue))
+ elif isAtkbackSkill:
+ hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("HurtFormula", 3))
+ GameWorld.DebugLog(" 反击伤害=%s" % (hurtValue))
+ else:
+ hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("HurtFormula", 4))
+ GameWorld.DebugLog(" 其他伤害=%s" % (hurtValue))
+
+ hurtValue = max(1, int(hurtValue)) # 负值、保底防范
+
+ return hurtValue, hurtTypes
+
+def CalcBounceHP(atkObj, defObj, hurtObj, curSkill):
+ '''计算反弹反弹伤害
+ '''
+ if not atkObj.GetCanAttack():
+ return
+
+ bounceHP = int(hurtObj.GetHurtHP() * random.uniform(0.1, 0.2))
+
+ if bounceHP <= 0:
+ return
+
+ remainHP = atkObj.GetHP() - bounceHP # 反弹允许弹到负值,如果最终吸血没有吸到正值则算死亡
+ hurtObj.SetBounceHP(bounceHP)
+ atkObj.SetHP(remainHP)
+ GameWorld.DebugLog(" 反弹伤害=%s,remainHP=%s" % (bounceHP, remainHP))
+
+ TurnAttack.AddTurnObjHurtValue(defObj, atkObj, bounceHP, bounceHP, isBounce=True)
+ return
+
+def CalcSuckBlood(atkObj, defObj, hurtObj, curSkill):
+ '''计算吸血
+ '''
+
+ suckHP = int(hurtObj.GetHurtHP() * random.uniform(0.1, 0.2))
+
+ if suckHP <= 0:
+ return
+
+ curHP = atkObj.GetHP()
+ maxHP = atkObj.GetMaxHP()
+ remainHP = min(curHP + suckHP, maxHP)
+ cureHP = remainHP - curHP # 实际治疗量
+
+ hurtObj.SetSuckHP(suckHP)
+ atkObj.SetHP(remainHP)
+ GameWorld.DebugLog(" 吸血=%s,remainHP=%s/%s" % (suckHP, remainHP, maxHP))
+
+ # 吸血暂定算治疗
+ TurnAttack.AddTurnObjCureHP(atkObj, atkObj, suckHP, cureHP)
+ return
+
+def CalcCureHP(userObj, tagObj, curSkill, largeNum=False):
+ ''' 计算治疗值
+ '''
+ cureBaseValue = 0 #治疗基础值
+ effIDNum = curSkill.FindEffectID(ChConfig.Def_Skill_Effect_Cure)
+ skillPer = curSkill.GetEffectValue(effIDNum, 0)
+ cureType = curSkill.GetEffectValue(effIDNum, 1)
+
+ #获得基础治疗值
+ if cureType == ChConfig.Def_Cure_Attack:
+ cureBaseValue = userObj.GetAtk()
+ elif cureType == ChConfig.Def_Cure_MaxHP:
+ cureBaseValue = userObj.GetMaxHP()
+ #elif cureType == ChConfig.Def_Cure_HurtValue:
+ # cureBaseValue = GameObj.GetLastHurtValue(userObj)
+ elif cureType == ChConfig.Def_Cure_TagMaxHP:
+ cureBaseValue = 0 if not tagObj else tagObj.GetMaxHP()
+
+ #skillPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(userObj, None, curSkill, ChConfig.TriggerType_AddHP)
+
+ # 回合制
+ curePer = 0 # 治疗加成
+ cureDefPer = 0 # 敌方的弱化治疗
+ angerOverflow = 0 # 怒气溢出值
+ if SkillCommon.isAngerSkill(curSkill):
+ angerOverflow = max(userObj.GetXP() - IpyGameDataPY.GetFuncCfg("AngerXP", 2), 0)
+ #enemyObj = TurnAttack.GetEnemyObj(userObj)
+ #curePer += GameObj.GetCurePer(userObj)
+ #if enemyObj:
+ # cureDefPer += GameObj.GetCureDefPer(enemyObj)
+
+ skillPer /= float(ChConfig.Def_MaxRateValue)
+ curePer /= float(ChConfig.Def_MaxRateValue)
+ cureDefPer /= float(ChConfig.Def_MaxRateValue)
+
+ baseValue = max(0, cureBaseValue) # 防止基值被弱化为负值,在恢复比例也是负值的情况下负负得正导致可以恢复血量
+
+ #公式计算治疗值
+ cureHP = eval(IpyGameDataPY.GetFuncCompileCfg("CureFormula", 1))
+ if not largeNum:
+ cureHP = min(cureHP, ChConfig.Def_UpperLimit_DWord)
+ cureHP = max(1, int(cureHP)) # 保底1点
+
+ GameWorld.DebugLog("计算治疗值(%s):skillID=%s,cureType=%s,baseValue=%s,skillPer=%s,curePer=%s,cureDefPer=%s,angerOverflow=%s"
+ % (cureHP, curSkill.GetSkillID(), cureType, baseValue, skillPer, curePer, cureDefPer, angerOverflow))
+ return cureHP
+
+def Sync_UseSkill(turnFight, curBatObj, useSkill):
+ ## 通知释放技能
+ poolMgr = ObjPool.GetPoolMgr()
+ clientPack = poolMgr.acquire(ChPyNetSendPack.tagSCUseSkill)
+ clientPack.ObjID = curBatObj.GetID()
+ clientPack.PMType = GetPMType(curBatObj, useSkill)
+ clientPack.BattleType = useSkill.GetBatType()
+ clientPack.CurHP = curBatObj.GetHP() % ChConfig.Def_PerPointValue
+ clientPack.CurHPEx = curBatObj.GetHP() / ChConfig.Def_PerPointValue
+ clientPack.SkillID = useSkill.GetSkillID()
+ clientPack.HurtList = []
+ for hurtObj in useSkill.GetHurtObjList():
+ hurt = poolMgr.acquire(ChPyNetSendPack.tagSCUseSkillHurt)
+ hurt.ObjID = hurtObj.GetObjID()
+ hurt.AttackTypes = hurtObj.GetHurtTypes()
+ hurt.HurtHP = hurtObj.GetHurtHP() % ChConfig.Def_PerPointValue
+ hurt.HurtHPEx = hurtObj.GetHurtHP() / ChConfig.Def_PerPointValue
+ hurt.CurHP = hurtObj.GetCurHP() % ChConfig.Def_PerPointValue
+ hurt.CurHPEx = hurtObj.GetCurHP() / ChConfig.Def_PerPointValue
+ hurt.SuckHP = min(hurtObj.GetSuckHP(), ChConfig.Def_UpperLimit_DWord)
+ hurt.BounceHP = min(hurtObj.GetBounceHP(), ChConfig.Def_UpperLimit_DWord)
+ clientPack.HurtList.append(hurt)
+ clientPack.HurtCount = len(clientPack.HurtList)
+ turnFight.addBatPack(clientPack)
+ return
+
+def Sync_PropertyRefreshView(turnFight, curBatObj, attrID, value, diffValue, diffType=0, skillID=0, relatedSkillID=0):
+ '''通知对象属性刷新展示B418
+ @param attrID: 通知变化的属性ID
+ @param diffValue: 变化值
+ @param diffType: 变化类型,0-减少;1-增加
+ @param skillID: 使用的技能表ID,即哪个技能的效果
+ @param relatedSkillID: 关联的技能ID,一般是主技能ID,非主技能额外触发的为0
+ '''
+ if attrID not in ChConfig.CDBRefresh_AttrIDDict:
+ return
+ refreshType, isBig = ChConfig.CDBRefresh_AttrIDDict[attrID]
+ poolMgr = ObjPool.GetPoolMgr()
+ clientPack = poolMgr.acquire(ChPyNetSendPack.tagSCObjPropertyRefreshView)
+ clientPack.ObjID = curBatObj.GetID()
+ clientPack.RefreshType = refreshType
+ if isBig:
+ clientPack.Value = value % ShareDefine.Def_PerPointValue
+ clientPack.ValueEx = value / ShareDefine.Def_PerPointValue
+ clientPack.DiffValue = diffValue % ShareDefine.Def_PerPointValue
+ clientPack.DiffValueEx = diffValue / ShareDefine.Def_PerPointValue
+ else:
+ clientPack.Value = value
+ clientPack.ValueEx = 0
+ clientPack.DiffValue = diffValue
+ clientPack.DiffValueEx = 0
+ clientPack.DiffType = diffType
+ clientPack.SkillID = skillID
+ clientPack.RelatedSkillID = relatedSkillID
+ turnFight.addBatPack(clientPack)
+ return
--
Gitblit v1.8.0