using System; using System.Collections.Generic; using System.Text; using CommonAI.ZoneClient; using CommonAI.Zone.Helper; using CommonLang; namespace CommonAI.Zone.Instance { /// /// 可拾取的道具 /// public class InstanceItem : InstanceZoneObject, ViewTrigger.ViewTriggerListener { //拾取信息 public HashMap unitPickInfo = null; public int TotalPickTimes = 0; public string Name { get; private set; } public string DisPlayName { get; private set; } public string Alias { get { return mSyncInfo.Alias; } set { mSyncInfo.Alias = value; } } public override float Weight { get { return 0; } } protected ItemTemplate mData; protected SyncItemInfo mSyncInfo; protected ViewTrigger mViewTrigger; protected bool mClientVisible; protected bool mSyncPos; protected InstanceUnit mItemCreater; protected TimeExpire mViewTriggerTimer; protected TimeExpire mRemovedExpire; public int mFrom; //0:场景,1:游戏服 public bool mPosValid = true; public InstanceItem(InstanceZone zone, ItemTemplate item, string name, int force, InstanceUnit creater, string disPlayName,int from) : base(zone, false) { this.Name = (name == null) ? "" : name; this.DisPlayName = (disPlayName == null) ? "" : disPlayName; this.mData = item; if(mData.LifeTimeMS > 0) { this.mRemovedExpire = new TimeExpire(mData.LifeTimeMS); } else { this.mRemovedExpire = null; } //this.mRemovedExpire = new TimeExpire(mData.LifeTimeMS); this.mViewTrigger = new ViewTriggerRoundBody(zone, item.BodySize); this.mViewTrigger.setListener(this); this.mViewTrigger.Enable = false; if (!mData.Pickable) { this.mViewTriggerTimer = new TimeExpire(item.GotCoolDownTimeMS); } this.mSyncInfo = new SyncItemInfo(zone.IsHalfSync); this.mSyncInfo.TemplateID = mData.ID; this.mSyncInfo.Force = force; this.mSyncInfo.showItemLeftTimes = mData.showLifeTime; if(mData.showLifeTime) { this.mSyncInfo.ItemTotalTimeMS = mData.LifeEndTime; } else { this.mSyncInfo.ItemTotalTimeMS = mData.LifeTimeMS; } this.Force = force; this.mClientVisible = item.ClientVisible; this.mSyncPos = false;// zone.SyncPos; this.mItemCreater = creater; this.mFrom = from; if(this.Info.maxPickPlayers > 0 || this.Info.maxPickTimes > 0) { unitPickInfo = new HashMap(Math.Max(1, this.Info.maxPickPlayers/2)); } } public ItemTemplate Info { get { return mData; } } public int Force { get; private set; } public override bool IntersectMap { get { return false; } } public override bool IntersectObj { get { return false; } } public override bool Moveable { get { return false; } } public override float BodyBlockSize { get { return mData.BodySize; } } override public float BodyHitSize { get { return mData.BodySize; } } public override float BodyHeight { get { return mData.BodySize; } } public override bool ClientVisible { get { return mClientVisible; } } public override bool SyncPos { get { return mSyncPos; } } public InstanceUnit ItemCreater { get { return mItemCreater; } } public int ExpireTimeMS { get { if(mRemovedExpire != null) { return mRemovedExpire.TotalTimeMS - mRemovedExpire.PassTimeMS; } return int.MaxValue; } } public bool IsPosValid() { return this.mPosValid; } public void setPosNotValid() { this.mPosValid = false; } public override SyncObjectInfo GenSyncInfo(bool net) { return GenSyncItemInfo(net, null); } public SyncItemInfo GenSyncItemInfo(bool net, string playerId) { mSyncInfo.ItemExpireTimeMS = this.ExpireTimeMS; mSyncInfo.isCanPick = IsCanPick(playerId); return mSyncInfo; } //针对拾取人数上限控制是否移除 public bool IsPickAll() { if(this.Info.maxPickPlayers > 0 && this.Info.maxPickTimes > 0) { return this.TotalPickTimes >= (this.Info.maxPickPlayers * this.Info.maxPickTimes); } return false; } public bool IsCanPick(String playerId) { if (this.unitPickInfo == null) { return true; } if (this.Info.maxPickTimes > 0) { if (playerId != null && this.unitPickInfo.ContainsKey(playerId)) { return this.unitPickInfo.Get(playerId) < this.Info.maxPickTimes; } else { return this.Info.maxPickPlayers == 0 || this.unitPickInfo.Count < this.Info.maxPickPlayers; } } return this.unitPickInfo.Count < this.Info.maxPickPlayers || (playerId != null && this.unitPickInfo.ContainsKey(playerId)); } protected override void onAdded(bool pointLv) { this.mSyncInfo.x = X; this.mSyncInfo.y = Y; this.mSyncInfo.ObjectID = base.ID; this.mSyncInfo.direction = Direction; this.mSyncInfo.Alias = this.Alias; this.mSyncInfo.Name = this.DisPlayName; } protected override void Disposing() { base.Disposing(); mViewTrigger.Dispose(); } protected override void onRemoved() { } protected override void onUpdate(bool slowRefresh) { if (IsPaused) { return; } if (mRemovedExpire != null && mRemovedExpire.Update(Parent.UpdateIntervalMS)) { Parent.RemoveObject(this); } if (mViewTriggerTimer != null && mViewTriggerTimer.Update(Parent.UpdateIntervalMS)) { mViewTrigger.Enable = true; mViewTrigger.onLookUpdate(X, Y); } } public virtual bool IsPickable(InstanceUnit u) { if (this.Info.OnlyForShow) { return false; } if (!this.mPosValid) { return false; } if(u.IsDead()) { return false; } /*if (!mData.Pickable)//此参数为是否可手动拾取,而非是否能拾取 { return false; }*/ if (mData.PlayerOnly && (!u.IsPlayer)) { return false; } if (!this.Enable) { return false; } if (mData.DropForAll || Force == u.Force) { if (tryPickItem(u) && Parent.cb_unitTryPickItem(u, this)) { return true; } } return false; } public bool DirectPickItem(InstanceUnit u,System.Action action = null) { if (IsPickable(u)) { Parent.cb_unitFinishPickItem(u, this); bool remove; int pickTimes; if (u.doGotInstanceItem(this, out remove, out pickTimes)) { if (Info.GotEffectSelf != null) { Parent.queueEvent(new AddEffectEvent(this.ID, X, Y, Direction, Info.GotEffectSelf)); } u.queueEvent(new UnitGotInstanceItemEvent(u.ID, this.ID)); if (remove) { if(action != null) { action.Invoke(); } mViewTrigger.Enable = false; Parent.RemoveObject(this); } } return true; } return false; } public bool PickItem(InstanceUnit u) { if (IsPickable(u)) { if (Parent.TouchObject2(u, this)) { if (tryPickItem(u) && Parent.cb_unitTryPickItem(u, this)) { u.startPickProgressObject(this, mData.PickTimeMS, (unit, pickable) => { if (this.Enable) { Parent.cb_unitFinishPickItem(u, this); bool remove; int pickTimes; if (u.doGotInstanceItem(this, out remove, out pickTimes)) { if (Info.GotEffectSelf != null) { Parent.queueEvent(new AddEffectEvent(this.ID , X, Y, Direction, Info.GotEffectSelf)); } InstancePlayer player = (u as InstancePlayer); int flag = this.IsCanPick(player == null ? null : player.PlayerUUID) ? 0 : 1; u.queueEvent(new UnitGotInstanceItemEvent(u.ID, this.ID, (byte)flag)); //如果标记移除,或者拾取人数达上限 if (remove || this.IsPickAll()) { mViewTrigger.Enable = false; Parent.RemoveObject(this); } } } }); return true; } } } return false; } private bool tryPickItem(InstanceUnit unit) { if (!Parent.IsVisibleAOI(unit, this)) { return false; } bool ret = true; if (mTryPickItem != null) { foreach (TryPickItem trypick in mTryPickItem.GetInvocationList()) { if (!trypick.Invoke(this, unit)) { ret = false; } } } return ret; } #region _Collides_ void ViewTrigger.ViewTriggerListener.onObjectEnterView(ViewTrigger src, InstanceZoneObject obj) { if (!mData.Pickable && !mData.OnlyForShow) { InstanceUnit u = obj as InstanceUnit; if (mData.PlayerOnly && (!u.IsPlayer)) { return; } if ((mData.DropForAll || Force == u.Force) && this.IsPickable(u)) { bool remove; int pickTimes; if (u.doGotInstanceItem(this, out remove, out pickTimes)) { u.NotifyRemoveDropItemB2C(this); if (Info.GotEffectSelf != null) { Parent.queueEvent(new AddEffectEvent(this.ID, X, Y, Direction, Info.GotEffectSelf)); } u.queueEvent(new UnitGotInstanceItemEvent(u.ID, this.ID)); if (remove) { mViewTrigger.Enable = false; Parent.RemoveObject(this); } } } } } void ViewTrigger.ViewTriggerListener.onObjectLeaveView(ViewTrigger src, InstanceZoneObject obj) { } bool ViewTrigger.ViewTriggerListener.select(ViewTrigger src, InstanceZoneObject obj) { if (obj == this) { return false; } else if (obj is InstanceUnit) { return true; } return false; } public override String GetTemplateData() { return "Item:" + this.Info.ID; } #endregion #region _API_ public ItemTemplate get_template() { return mData; } public bool is_attribute(string key) { return IsAttribute(key); } public void set_attribute(string key, object value) { SetAttribute(key, value); } public object get_attribute(string key) { return GetAttribute(key); } #endregion #region _Delegate_ /// /// 单位尝试检取道具监听, /// 返回False禁止检取 /// /// public delegate bool TryPickItem(InstanceItem item, InstanceUnit unit); private TryPickItem mTryPickItem; public event TryPickItem OnTryPickItem { add { mTryPickItem += value; } remove { mTryPickItem -= value; } } protected override void clearEvents() { base.clearEvents(); this.mTryPickItem = null; } #endregion } }