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
}
}