using CommonAI.Zone; using CommonLang; using System.Collections.Generic; using XmdsCommon.Message; using XmdsCommon.Plugin; using XmdsCommonServer.Message; using XmdsCommonServer.Plugin.Units; using XmdsCommonServer.Plugin.XmdsSkillTemplate.Skills; using CommonAI.Zone.Instance; using System; using CommonLang.Vector; using XmdsCommon.EditorData; using CommonAI.Zone.Formula; using CommonAI.Data; using CommonAI; using CommonAI.data; using XmdsCommonSkill.Plugin.CardSkill; namespace XmdsCommonServer.Plugin { public partial class XmdsVirtual_Player : XmdsVirtual { /// /// 攻击记录. /// private HashMap mAtkRecordMap = new HashMap(); /// /// PK值在线计时器. /// private TimeInterval mPKValueCycleTimer = null; /// /// PK信息. /// private PKInfo mPKInfo = null; /// /// 药剂HP恢复. /// private ItemRecoveryTask mHPRecoveryTask = new ItemRecoveryTask(); /// /// 宠物. /// private XmdsVirtual_Pet mPet = null; protected long mPkTime = 0; public XmdsVirtual_Player(XmdsInstancePlayer unit) : base(unit) { unit.OnRebirth += Unit_OnRebirth; unit.OnRemoved += Unit_OnRemoved; } private void Unit_OnRemoved(CommonAI.Zone.Instance.InstanceUnit unit) { //主人离开场景,移除宠物. if (mPet != null) { DismissPet(); } } private void Unit_OnRebirth(CommonAI.Zone.Instance.InstanceUnit unit) { //重置遗言. SyncTestament(0); } public void SyncTestament(byte testamentID) { if (mProp.ServerData.BaseInfo.Testament != testamentID) { mProp.ServerData.BaseInfo.Testament = testamentID; SyncPlayerVisibleData(); SendTestamentChangeEventB2C(testamentID); } } /** 获得宠物天赋加成 */ public override int GetPetTalentAddition(UnitFateType type) { if(mPet != null && type == mPet.GetUnitFateType()) { return mPet.GetPetTalentAddition(type); } return 0; } public override XmdsVirtual_Player GetPlayerUnit() { return this; } #region override. protected override void Init(bool pointLv) { InitPKCycleTimer(); InitQuestData(); // InitQuestFlags(); this.mProp.ServerData.PlayerEntered = true; //同步客户端可见信息. //设置发给别的玩家显示信息// PlayerVisibleDataB2C pvdb2c = new PlayerVisibleDataB2C(); //avatar信息. pvdb2c.AvatarList = mProp.ServerData.AvatarList; //基础信息. pvdb2c.BaseInfo = mProp.ServerData.BaseInfo; //PK相关信息. pvdb2c.UnitPKInfo = mProp.ServerData.UnitPKInfo; //场景数据. pvdb2c.UnitSceneInfo = mProp.ServerData.UnitSceneInfo; mUnit.SetVisibleInfo(pvdb2c); mPKInfo = this.mProp.ServerData.UnitPKInfo; #region 宠物数据MOCK. //-------------------------------------------------. /* //宠物Mock数据.测试数据,当前宠物为无敌状态. PetData pd = new PetData(); pd.PetConfig = new XmdsPetConifg(); pd.PetConfig.Mode = XmdsPetConifg.XmdsPetFollowMode.ActiveAtk; pd.BaseInfo = new PetBaseInfo(); XmdsUnitSkillInfo skillInfo = new XmdsUnitSkillInfo(); List l = new List(); GameSkill gs = new GameSkill(); gs.SkillID = 100101; gs.SkillLevel = 1; gs.SkillType = GameSkill.XmdsSkillType.normalAtk; l.Add(gs); skillInfo.UnitSkills = l; pd.SkillInfo = skillInfo; UnitInfo info = XmdsBattleSkill.GetUnitInfo(DEFAULT_TEMPLATE_ID); this.mProp.ServerData.UnitPetData = pd; this.mProp.ServerData.UnitPetData.BaseInfo.level = 1; this.mProp.ServerData.UnitPetData.UnitProp = (info.Properties as XmdsUnitProperties).ServerData.Prop; this.mProp.ServerData.UnitPetData.UnitProp.MinPhy = 1;// 4803; this.mProp.ServerData.UnitPetData.UnitProp.MaxPhy = 1;// 4921; this.mProp.ServerData.UnitPetData.UnitProp.Hit = 710; this.mProp.ServerData.UnitPetData.UnitProp.Crit = 50; this.mProp.ServerData.UnitPetData.UnitProp.Dodge = 1; this.mProp.ServerData.UnitPetData.UnitProp.Rescrit = 949; this.mProp.ServerData.UnitPetData.UnitProp.Ac = 2229; this.mProp.ServerData.UnitPetData.UnitProp.Resist = 1500; this.mProp.ServerData.UnitPetData.UnitProp.HP = 1; */ //-------------------------------------------------. #endregion //宠物数据. ChangePet(this.mProp.ServerData.UnitPetData); if (mProp.BotTestTemplate) { (this.mUnit as XmdsInstancePlayer).SendBotTestAutoFight(); } } public override void doEvent(JSGCustomOpType type) { if(type == JSGCustomOpType.UpdateAutoBattleFlag) { SetAutoBattleB2C evt = new SetAutoBattleB2C(); InstancePlayer playerUnit = mUnit as InstancePlayer; evt.isAutoBattle = playerUnit.IsGuard ? 1 : 0; this.mUnit.queueEvent(evt); } } public void OnUnitReEnter(UnitInfo temp, int force, int level, Vector2 enterPos) { SyncClientData(); } protected override void SyncClientData() { base.SyncClientData(); SyncPKValue(mPKInfo.CurPKValue, true); } public override void SyncBattlePropsFields(ulong mask) { if (mask != 0) { if (mBattlePropChangeEvt == null) { mBattlePropChangeEvt = new PlayerBattlePropChangeEventB2C(); } mBattlePropChangeEvt.Mask |= mask; } } public long getPkTime() { return CUtils.CurrentTimeMS - mPkTime; } public int getPkValue() { return mPKInfo.CurPKValue; } public override void OnUnitDead(XmdsVirtual killer) { //怪物死亡时,需要计算组队分享人员名单. mHateSystem.CalAtkAssistantList(false); base.OnUnitDead(killer); } public override int OnHit(XmdsVirtual attacker, AttackSource source) { int ret = base.OnHit(attacker, source); if (ret > 0 && attacker is XmdsVirtual_Player) { mPkTime = CUtils.CurrentTimeMS; } return ret; } public override void OnHitOthter(XmdsVirtual target) { if (mHateSystem.ContainsID(target.mUnit.ID) == false) { mHateSystem.AddTarget(target); } if (CalPKValue(target) == true) { if ((target is XmdsVirtual_Player || target is XmdsVirtual_SummonUnit || target is XmdsVirtual_Pet) && target.GetCurPKLevel() == PKLevel.White) { string id = target.GetPlayerUUID(); if (id != this.GetPlayerUUID() && !string.IsNullOrEmpty(id)) { //判断该单位是否有被攻击过. if (mAtkRecordMap.ContainsKey(id) == false) { AtkRecordAdd(id); } } } } #region MOCK 恢复道具. //PropertyChangeEventR2B evt = new PropertyChangeEventR2B(); //evt.ChangeType = PropertyChangeEventR2B.PropertyChangeType.HP; //evt.ChangeValue = 10000; //evt.Duration = 10000; //evt.ChangeValueType = PropertyChangeEventR2B.ValueType.Value; //OnRceivePropertyChangeEventR2B(evt); #endregion } public override bool TryLaunchSkill(InstanceUnit.SkillState skill, ref InstanceUnit.LaunchSkillParam param) { #region PK保护. //var pkprotect = IsInPKProtect(param.TargetUnitID); //if (pkprotect) //{ // SendMsgToClient(CommonAI.XmdsConstConfig.TIPS_IN_PK_PROTECT); // return false; //} #endregion bool ret = base.TryLaunchSkill(skill, ref param); if (ret == true) { if (param.TargetUnitID != 0 && (this.mHateSystem.ContainsID(param.TargetUnitID) == false)) { InstanceUnit u = this.mUnit.Parent.getUnit(param.TargetUnitID); if (u != null && u != this.mUnit) { if (!this.IsAllies(u.Virtual as XmdsVirtual, false)) { this.mHateSystem.AddTarget(u.Virtual as XmdsVirtual); } } } } return ret; } public override void OnKillUnit(XmdsVirtual dead) { if (CalPKValue(dead) == true) { if (dead.IsPlayerUnit() && dead.GetCurPKLevel() == PKLevel.White && dead.GetPlayerUUID() != this.GetPlayerUUID()) { SyncPKValue(XmdsGameConfig.Instance.PK_KILL_ADD + this.mPKInfo.CurPKValue); } } #region Mock技能增删. /* List ret = new List(); GameSkill gs = new GameSkill(); gs.SkillID = 300010; gs.SkillLevel = ++skilllv; gs.SkillType = GameSkill.XmdsSkillType.active; gs.TalentSkillLevel = 1; ret.Add(gs); Mock_ReplaceSkill(ret); */ #endregion } protected override void OnCombatStateChange(BattleStatus status) { base.OnCombatStateChange(status); if (status == BattleStatus.None) { mAtkRecordMap.Clear(); } /*测试怪物伤害信息. GetMonsterSufferDamageInfoC2B evt = new GetMonsterSufferDamageInfoC2B(); evt.MonsterID = 3; (this.mUnit as XmdsInstancePlayer).OnReceiveGetMonsterSufferDamageInfoC2B(evt); */ } protected override bool JudgeChangeCombatStateChange(BattleStatus status, byte reason) { //普通情况下,召唤物未出战斗状态,主人也处于战斗状态. if (status == BattleStatus.None && reason == 0) { if (mSummonList != null && mSummonList.Count > 0) { for (int i = 0; i < mSummonList.Count; i++) { if (mSummonList[i].CombatState != BattleStatus.None) { return false; } } } //如果宠物在战斗状态,主人无法脱战. if (mPet != null && mPet.CombatState != BattleStatus.None) { return false; } } return true; } protected override void CombatStateConnect(BattleStatus status, byte reason) { //主人进入战斗状态,影响召唤物. if (mSummonList != null && mSummonList.Count > 0) { for (int i = 0; i < mSummonList.Count; i++) { mSummonList[i].SetCombatState(status); } } if (mPet != null && mPet.mUnit.IsDead() == false) { mPet.SetCombatState(status); } } public override string GetPlayerUUID() { return (mUnit as XmdsInstancePlayer).PlayerUUID; } public override bool IsMember(XmdsVirtual target, PKMode mode, bool includeSelf, bool onlyForTeam = false) { bool ret = false; if (this.mUnit == target.mUnit) { return includeSelf == true; } if (target.mUnit.Virtual is XmdsCommon.ZoneClient.XmdsClientVirtual.XmdsClientVirtual_Pet) { return true;//自动选取目标时选中宠物的bug } //非玩家单位统一走force. if (target.IsPlayerUnit() == false) { ret = this.mUnit.Force == target.mUnit.Force ? true : false; } else { switch (mode) { case PKMode.Peace://和平模式使用默认出生的force. //只用阵营会导致,不是队友,给他加增益buff得情况 ret = this.mUnit.Force == target.mUnit.Force ? true : false; if (ret && onlyForTeam) { ret = this.IsTeamMember(target.GetPlayerUUID()); } break; case PKMode.force://阵营模式使用Camp. ret = this.IsCampMember(target.GetForceID()); if (ret == false) { ret = this.IsTeamMember(target.GetPlayerUUID()); } break; case PKMode.Guild: ret = this.IsGuildMember(target.GetGuildID()); if (ret == false) { ret = this.IsTeamMember(target.GetPlayerUUID()); } break; case PKMode.Team: ret = this.IsTeamMember(target.GetPlayerUUID()); break; case PKMode.All: ret = (target.GetPlayerUUID() == this.GetPlayerUUID()); break; case PKMode.Justice: ret = target.GetCurPKLevel() == PKLevel.White ? true : false; if (ret == false) { ret = this.IsTeamMember(target.GetPlayerUUID()); } break; case PKMode.Server: ret = this.IsServerMember(target.GetServerID()); if (ret == false) { ret = this.IsTeamMember(target.GetPlayerUUID()); } break; } } return ret; } public override void OnUpdateTriggerSkill(int intervalMS, bool slowRefresh) { base.OnUpdateTriggerSkill(intervalMS, slowRefresh); UpdatePKCycleTimer(intervalMS); UpdateItemRecoveryTask(intervalMS); } public override bool IsPlayerUnit() { return true; } protected override void Dispose() { mUnit.OnRebirth -= Unit_OnRebirth; mUnit.OnRemoved -= Unit_OnRemoved; CleanSummonList(); if (mAtkRecordMap != null) { mAtkRecordMap.Clear(); } mPet = null; base.Dispose(); } public bool AllowUseAutoGuard() { bool ret = false; try { //机器人玩家默认可以使用自动战斗. if (mProp.BotTestTemplate) { return true; } ret = mProp.ServerData.UnitSceneInfo.AllowAutoGuard; } catch (Exception error) { ret = true; FormatLog(CommonLang.Log.LoggerLevel.ERROR, "AllowUseAutoGuard Error:{0}", error.ToString()); } return ret; } protected override void InitSceneInfo() { base.InitSceneInfo(); switch (this.mUnit.GetSceneType()) { case CommonAI.Data.SceneType.Dungeon://副本中索敌范围扩大. case CommonAI.Data.SceneType.DanTiao: case CommonAI.Data.SceneType.JJC: case CommonAI.Data.SceneType.GuildDungeon: case CommonAI.Data.SceneType.MengZhan: case CommonAI.Data.SceneType.FiveVFive: case CommonAI.Data.SceneType.GoblinTower: case CommonAI.Data.SceneType.SourceDungeon: case CommonAI.Data.SceneType.HaoYueJing: case CommonAI.Data.SceneType.GuildBoss: case CommonAI.Data.SceneType.SecretDungeon: case CommonAI.Data.SceneType.FightLevelUltra: case CommonAI.Data.SceneType.PickLotus: case CommonAI.Data.SceneType.CROSS_SERVER_NEW: case CommonAI.Data.SceneType.NCS_FengShen: case CommonAI.Data.SceneType.DEVIL: (this.mUnit as XmdsInstancePlayer).SetGuardSearchRange(XmdsConfig.Instance.DUNGEON_AUTO_GUARD_RANGE); break; case CommonAI.Data.SceneType.NCS_MutilCross: case CommonAI.Data.SceneType.NCS_DoubleCross: (this.mUnit as XmdsInstancePlayer).SetGuardSearchRange(XmdsConfig.Instance.PVP_AUTO_GUARD_RANGE); break; default: (this.mUnit as XmdsInstancePlayer).SetGuardSearchRange(XmdsConfig.Instance.NORMALSCENE_AUTO_GUARD_RANGE); break; } //针对一些特殊的副本,设置拾取范围(全部改成手动拾取,所以这里没啥用了) //switch (this.mUnit.GetSceneType()) //{ // case CommonAI.Data.SceneType.NCS_MutilCross: // case CommonAI.Data.SceneType.NCS_DoubleCross: // case CommonAI.Data.SceneType.NCS_FengShen: // case CommonAI.Data.SceneType.DEVIL: // this.mUnit.SetAutoPickRange(XmdsConstConfig.AUTOPICK_RANGE_PVP); // break; // default: // break; //} } #endregion #region private. private void SendTestamentChangeEventB2C(byte testamentID) { TestamentChangeEventB2C evt = new TestamentChangeEventB2C(); evt.TestamentID = testamentID; this.mUnit.queueEvent(evt); } private void SendPKLevelChangeEventB2C(PKLevel lv) { PlayerPKLvChangeEventB2C evt = new PlayerPKLvChangeEventB2C(); evt.CurLv = lv; this.mUnit.queueEvent(evt); } private void SendPKValueChangeEventB2C(int v) { PlayerPKValueChangeEventB2C evt = new PlayerPKValueChangeEventB2C(); evt.CurPKValue = v; this.mUnit.queueEvent(evt); } /// /// PK值在线衰退计时器. /// private void InitPKCycleTimer() { mPKValueCycleTimer = new TimeInterval(XmdsGameConfig.Instance.PK_VALUE_UPDATE_CYCLE); mPKValueCycleTimer.FirstTimeEnable = false; } /// /// 刷新计时器. /// /// private void UpdatePKCycleTimer(int intervalMS) { if (mPKInfo != null && mPKInfo.CurPKValue > 0 && mPKValueCycleTimer.Update(intervalMS)) { SyncPKValue(mPKInfo.CurPKValue - XmdsGameConfig.Instance.PK_VALUE_REDUCE); } } /// /// 攻击列表刷新. /// /// private void AtkRecordAdd(string id) { mAtkRecordMap.Add(id, id); SyncPKValue(XmdsGameConfig.Instance.PK_ATK_ADD + mPKInfo.CurPKValue); } /// /// 同步PK值. /// /// private void SyncPKValue(int v, bool refresh = false) { v = (int)CMath.getInRange(v, 0, int.MaxValue); if (mPKInfo.CurPKValue == v && refresh == false) { return; } mPKInfo.CurPKValue = v; //等于0时重置. if (mPKInfo.CurPKValue == 0 && mPKValueCycleTimer != null) { mPKValueCycleTimer.Reset(); } SendPKValueChangeEventB2C(v); //等级变更时推送给客户端. PKLevel l; if (mPKInfo.CurPKValue == 0) { l = PKLevel.White; } else if (CMath.isIncludeEqual(mPKInfo.CurPKValue, XmdsGameConfig.Instance.PK_LEVEL_BLACK_RANGE[0], XmdsGameConfig.Instance.PK_LEVEL_BLACK_RANGE[1])) { l = PKLevel.Black; } else if (CMath.isIncludeEqual(mPKInfo.CurPKValue, XmdsGameConfig.Instance.PK_LEVEL_YELLOW_RANGE[0], XmdsGameConfig.Instance.PK_LEVEL_YELLOW_RANGE[1])) { l = PKLevel.Yellow; } else { l = PKLevel.Red; } if (mPKInfo.CurPKLevel != l) { mPKInfo.CurPKLevel = l; SyncPlayerVisibleData(); SendPKLevelChangeEventB2C(l); } } private void UpdateItemRecoveryTask(int intervalMS) { mHPRecoveryTask.Update(intervalMS); } private bool IsInPKProtect(uint objID) { bool ret = false; //野外场景做判断. if (GetCurSceneType() != XmdsServerSceneData.NORMAL_MAP) { return ret; } //自己等级. int unitlv = this.GetUnitLv(); //对方等级. int targetUnitLv = 0; uint id = objID; if (id != 0 && id != this.mUnit.ID) { var target = this.mUnit.Parent.getUnit(id); if (target != null) { var uuid = (target.Virtual as XmdsVirtual).GetPlayerUUID(); var targetplayer = this.mUnit.Parent.getPlayerByUUID(uuid); if (targetplayer != null) { targetUnitLv = (targetplayer.Virtual as XmdsVirtual).GetUnitLv(); //小于等于保护等级,不受伤害. if (targetUnitLv <= XmdsConfig.Instance.PK_PROTECT_LV || unitlv <= XmdsConfig.Instance.PK_PROTECT_LV) { ret = true; } } } } return ret; } //消耗过大,暂时屏蔽,后期考虑优化方案 public override bool IsAttackable(XmdsVirtual attacker) { //只在野外地图下判断. //if (GetCurSceneType() == XmdsServerSceneData.NORMAL_MAP) //{ // //自己等级. // int unitLv = GetUnitLv(); // int attackerLv = 0; // string uuid = attacker.GetPlayerUUID(); // var v = this.mUnit.Parent.getPlayerByUUID(uuid); // if (v != null && v != this.mUnit) // { // attackerLv = (v.Virtual as XmdsVirtual_Player).GetUnitLv(); // if (attackerLv <= XmdsConfig.Instance.PK_PROTECT_LV || unitLv <= XmdsConfig.Instance.PK_PROTECT_LV) // { // return false; // } // } //} return true; } public class ItemRecoveryTask { public const int CYCLE_TIME = 500; private XmdsVirtual mOwner; private PropertyChangeEventR2B mEvt; private int mLifeTime = -1; private int mPassTime; private int mTimes = 1; private bool showFloatTips = false; public ItemRecoveryTask() { } public void Init(XmdsVirtual zv, PropertyChangeEventR2B evt, bool show) { mOwner = zv; mEvt = evt; mPassTime = CYCLE_TIME; //剩余时间. mLifeTime = (int)(evt.TimestampMS - TimeUtil.GetTimestampMS()); //每秒次数. mTimes = (evt.Duration / CYCLE_TIME); showFloatTips = show; } public void Update(int intervalMS) { if (!IsEnd()) { if (mPassTime >= CYCLE_TIME) { mPassTime -= CYCLE_TIME; switch (mEvt.ChangeType) { case PropertyChangeEventR2B.PropertyChangeType.HP: mOwner.AddHP(mEvt.ChangeValueType, (mEvt.ChangeValue * 1.0f / mTimes), showFloatTips); break; default: break; } } mPassTime += intervalMS; mLifeTime -= intervalMS; } } private bool IsEnd() { return (mLifeTime < 0); } } #endregion #region SummonUnit. private List mSummonList = new List(); public void AddSummonUnitList(XmdsVirtual_SummonUnit unit) { mSummonList.Add(unit); unit.mUnit.OnDead += MUnit_OnDead; } private void MUnit_OnDead(CommonAI.Zone.Instance.InstanceUnit unit, CommonAI.Zone.Instance.InstanceUnit attacker) { XmdsVirtual_SummonUnit v = unit.Virtual as XmdsVirtual_SummonUnit; if (v != null && mSummonList != null) { unit.OnDead -= MUnit_OnDead; mSummonList.Remove(v); } } public int GetSummonUnitListCount() { return mSummonList.Count; } public XmdsVirtual_SummonUnit GetFirstTimesupSummonUnit() { if (mSummonList.Count > 0) { return mSummonList[0]; } return null; } public void CleanSummonList() { if (mSummonList != null && mSummonList.Count > 0) { for (int i = 0; i < mSummonList.Count; i++) { mSummonList[i].mUnit.OnDead -= MUnit_OnDead; } mSummonList.Clear(); } } #endregion #region Pet. public XmdsVirtual_Pet GetPet() { return mPet; } public override InstanceUnit GetPetUnit() { if(mPet != null) return mPet.mUnit; return null; } private void SummonPetData(PetData data) { if (data == null) { return; } var pos = mUnit.Parent.PathFinder.FindNearMoveableNode( mUnit.X, mUnit.Y, XmdsConfig.Instance.PET_IDLE_FOLLOW_MAX_DISTANCE, true); if (pos == null) { log.Error(" SummonPetData pos = null"); return; } UnitInfo info = XmdsBattleSkill.GetUnitInfo(XmdsConstConfig.DEFAULT_PET_TEMPLATE_ID); if(info == null) { log.Warn("找不到宠物模板:" + XmdsConstConfig.DEFAULT_PET_TEMPLATE_ID); return ; } AddUnitEvent aue = null; XmdsUnitProperties prop = info.Properties as XmdsUnitProperties; //单位战斗属性赋值. //单位等级. prop.ServerData.BaseInfo.UnitLv = data.BaseInfo.level; //进阶等级. prop.ServerData.BaseInfo.StateLv = data.BaseInfo.StateLv; //能力赋值. prop.ServerData.Prop = data.UnitProp; //技能赋值. prop.ServerData.Skills = data.SkillInfo; var unit = (mUnit.Parent.AddUnit( info, info.Name, mUnit.Force, data.BaseInfo.level, pos.PosX, pos.PosY, mUnit.Direction, out aue, mUnit)) as XmdsInstancePet; var petVirtual = (unit.Virtual) as XmdsVirtual_Pet; data.BaseInfo.MasterID = this.mUnit.ID; petVirtual.InitVisibleData(data.BaseInfo); petVirtual.SetMaster(this); petVirtual.SetFollowMode(data.PetConfig.Mode); //设置宠物. mPet = petVirtual; //设置主人. unit.Master = this.mUnit; //宠物死亡后,清空引用避免内存泄露. unit.OnDead += PetUnit_OnDead; } private void PetUnit_OnDead(InstanceUnit unit, InstanceUnit attacker) { unit.OnDead -= PetUnit_OnDead; mPet = null; } /// /// 遣散宠物. /// private void DismissPet() { if (mPet != null) { this.mUnit.Parent.RemoveObjectByID(mPet.mUnit.ID); mPet = null; } } private void ChangePet(PetData data) { if (mPet != null) { DismissPet(); } //召唤宠物. SummonPetData(data); } //宠物基础属性变更. private void UpdatePetBaseInfo(PetBaseInfo info) { //基础信息更新. if (mPet != null) { mPet.UpdateBaseInfo(info); } } //所有宠物相关属性变更. private void UpdatePetData(PetData data) { if (mPet != null) { //更新基础信息. UpdatePetBaseInfo(data.BaseInfo); //属性变更. mPet.UpdatePetProps(data.UnitProp); } } private void UpdatePetSkillInfo(PetSkillChangeEventR2B evt) { if (mPet != null) { mPet.OnReceivePetSkillChangeEventR2B(evt); } } #endregion } }