using CommonAI.Zone.ZoneEditor; using CommonAI.ZoneClient; using CommonLang; using System; using CommonLang.Vector; using CommonAI.Zone; using System.Collections.Generic; using XmdsCommon.Plugin; using CommonAI.Zone.Helper; namespace XmdsCommon.ZoneClient { public class HZZoneLayer : ZoneLayer { private List mSafeAreaList; public HZZoneLayer(EditorTemplates dataroot, ILayerClient client) : base(dataroot, client) { this.LayerInit += HZZoneLayer_LayerInit; } private void HZZoneLayer_LayerInit(ZoneLayer layer) { //扫出所有安全区域. ICollection list = layer.Flags; if (list == null) { return; } mSafeAreaList = new List(); ZoneEditorArea zea = null; foreach (ZoneFlag e in list) { if (e is ZoneEditorArea) { zea = e as ZoneEditorArea; if (zea.CurrentMapNodeValue == XmdsMapBlock.BLOCK_VALUE_SAFE) { mSafeAreaList.Add(zea); } } } } public override bool IsCanPickItem(ZoneActor owner, ZoneItem item) { if (item == null) { return false; } if (IsTeamPickableItem(owner, item)) { return true; } if (IsPickableItem(owner, item)) { return true; } return false; } /// /// 获取当前可检取道具 /// /// /// /** public override ZoneItem GetNearPickableItem(ZoneActor owner) { ZoneItem ret = null; ForEachNearObjects(owner.X, owner.Y, (ZoneItem item, ref bool cancel) => { if (IsTeamPickableItem(owner, item)) { ret = item; cancel = true; } }); if (ret != null) { return ret; } ForEachNearObjects(owner.X, owner.Y, (ZoneItem item, ref bool cancel) => { if (IsPickableItem(owner, item)) { ret = item; cancel = true; } }); return ret; } **/ public virtual bool IsTeamPickableItem(ZoneActor owner, ZoneItem item, bool no_touch = false) { if (no_touch || item.Info.Pickable && (item.Info.DropForAll || item.Force == owner.Force)) { if (CMath.intersectRound(item.X, item.Y, item.Info.BodySize, owner.X, owner.Y, owner.Info.BodySize)) { XmdsCommon.Message.DropItem di = item.SyncInfo.ExtData as XmdsCommon.Message.DropItem; if (di == null) { return true; } else { //Mode 1 自由拾取 只检查自己背包 //Mode 2, 队伍背包,只检查队伍背包 //Mode 3, Roll点,只判断所有权 bool is_owner = false; if (di.PlayerUUID != null) { for (int i = 0; i < di.PlayerUUID.Count; i++) { if (owner.PlayerUUID == di.PlayerUUID[i]) { is_owner = true; break; } } } if (is_owner)//有归属者. { if (di.Mode == 2) { return true; } else { return false; } } else { if (item.PassTimeMS >= di.ProtectTime) { return true; } else { return false; } } } } } return false; } public override bool IsPickableItem(ZoneActor owner, ZoneItem item, bool no_touch = false) { if (!item.Info.OnlyForShow && (item.Info.DropForAll || item.Force == owner.Force)) { if (no_touch || CMath.intersectRound(item.X, item.Y, item.Info.BodySize, owner.X, owner.Y, owner.Info.BodySize)) { XmdsCommon.Message.DropItem di = item.SyncInfo.ExtData as XmdsCommon.Message.DropItem; if (di == null) { return true; } else { bool is_owner = false; if (di.PlayerUUID != null) { for (int i = 0; i < di.PlayerUUID.Count; i++) { if (owner.PlayerUUID == di.PlayerUUID[i]) { is_owner = true; break; } } } if (is_owner) { return true; } else { //if (item.PassTimeMS >= di.ProtectTime) if (item.PassTimeMS >= di.ProtectTime || item.SyncInfo.ItemExpireTimeMS == int.MaxValue) //edited by vajre 用于跨服拾取别人的装备 { return true; } else { return false; } } } } } return false; } public bool IsInSafeArea(ZoneUnit src) { var sa = GetArea(src.X, src.Y); //var sa = mUnit.CurrentArea; if (sa != null && sa.CurrentMapNodeValue == XmdsMapBlock.BLOCK_VALUE_SAFE) { return true; } else { return false; } } public override bool IsAttackable(ZoneUnit src, ZoneUnit target, SkillTemplate.CastTarget expectTarget) { //绝对中立阵营,不能被选为攻击目标. if (target.Force == 0 || target.HP <= 0) { return false; } switch (expectTarget) { case SkillTemplate.CastTarget.Enemy: { bool isEnemy = (src.Virtual as XmdsClientVirtual.XmdsClientVirtual).IsEnemy(target); if (src.Info.UType == UnitInfo.UnitType.TYPE_PLAYER && target.Info.UType == UnitInfo.UnitType.TYPE_PLAYER) { if (IsInSafeArea(src) || IsInSafeArea(target)) { return false; } else { return isEnemy; } } else { return isEnemy; } } case SkillTemplate.CastTarget.PetForMaster: if (src.Info.UType == UnitInfo.UnitType.TYPE_PET) { return (src != target) && (src.Force == target.Force); } return false; case SkillTemplate.CastTarget.Alias: case SkillTemplate.CastTarget.AlliesExcludeSelf: return (src != target) && (src.Virtual as XmdsClientVirtual.XmdsClientVirtual).IsAllies(target); case SkillTemplate.CastTarget.AlliesIncludeSelf: return (src.Virtual as XmdsClientVirtual.XmdsClientVirtual).IsAllies(target); case SkillTemplate.CastTarget.EveryOne: return true; case SkillTemplate.CastTarget.EveryOneExcludeSelf: return (src != target); case SkillTemplate.CastTarget.Self: return src == target; case SkillTemplate.CastTarget.EnemyAndSelf: { if (src == target) { return true; } else { bool isEnemy = (src.Virtual as XmdsClientVirtual.XmdsClientVirtual).IsEnemy(target); if (src.Info.UType == UnitInfo.UnitType.TYPE_PLAYER && target.Info.UType == UnitInfo.UnitType.TYPE_PLAYER) { if (IsInSafeArea(src) || IsInSafeArea(target)) { return false; } else { return isEnemy; } } else { return isEnemy; } } }; case SkillTemplate.CastTarget.NA: default: return false; } } /// /// 获得范围内符合目标条件的单位. /// /// /// /// /// public virtual ZoneUnit GetNearTarget(ZoneActor owner, float range, SkillTemplate.CastTarget expect = SkillTemplate.CastTarget.Enemy) where T : XmdsClientVirtual.XmdsClientVirtual { ZoneUnit min = null; float min_len = range * range; ForEachNearObjects(owner.X, owner.Y, range, (ZoneUnit u, ref bool cancel) => { if (u.Virtual is T) { if (IsAttackable(owner, u, expect)) { float len = MathVector.getDistanceSquare(u.X, u.Y, owner.X, owner.Y) - u.Info.BodyHitSize; if (min_len >= len) { min_len = len; min = u; } } } }); return min; } /// /// 获得范围内血量最少的单位. /// /// /// /// /// public virtual ZoneUnit GetWeakestTarget(ZoneActor owner, float range, SkillTemplate.CastTarget expect = SkillTemplate.CastTarget.Enemy) where T : XmdsClientVirtual.XmdsClientVirtual { using (var list = ListObjectPool.AllocAutoRelease()) { ForEachNearObjects(owner.X, owner.Y, range, (ZoneUnit u, ref bool cancel) => { if (u.Virtual is T) { if (CMath.intersectRound(owner.X, owner.Y, range, u.X, u.Y, u.Info.BodyHitSize)) { if (IsAttackable(owner, u, expect)) { list.Add(u); } } } }); if (list.Count > 0) { list.Sort((a, b) => { if (a.HP != b.HP) { return a.HP - b.HP; } float da = CMath.getDistanceSquare(a.X, a.Y, owner.X, owner.Y) - a.Info.BodyHitSize; float db = CMath.getDistanceSquare(b.X, b.Y, owner.X, owner.Y) - b.Info.BodyHitSize; return (int)(da - db); }); return list[0]; } else { return null; } } } public virtual ZoneEditorArea GetNearSafeAreaPos(float x, float y) { if (mSafeAreaList == null) { return null; } ZoneEditorArea ret = null; if (mSafeAreaList.Count > 0) { mSafeAreaList.Sort((a, b) => { float da = CMath.getDistanceSquare(a.X, a.Y, x, y); float db = CMath.getDistanceSquare(b.X, b.Y, x, y); return (int)(da - db); }); ret = mSafeAreaList[0]; } return ret; } } }