using UnityEngine;
|
using System.Collections.Generic;
|
|
using System;
|
using vnxbqy.UI;
|
using LitJson;
|
using System.Collections;
|
|
public class DropItemManager
|
{
|
public class DropObject
|
{
|
public DropItem dropItem;
|
public int dropID;
|
public int itemID;
|
public int ownerType;
|
public uint ownerID;
|
public float remainTime;
|
public JsonData userData;
|
}
|
|
public static UnityEngine.Events.UnityAction<int> pickUpCallBack;
|
public static event Action<List<Vector3>> guardPickupCallBack;
|
|
private static Dictionary<int, DropObject> m_MapItemDict = new Dictionary<int, DropObject>();
|
private static List<int> m_MapItemIdList = new List<int>();
|
private static Dictionary<int, int> instanceIdToItemId = new Dictionary<int, int>();
|
private static Dictionary<int, Vector3> intstanceIdToPosition = new Dictionary<int, Vector3>();
|
public static bool StopMissionPickup = false;
|
private static Dictionary<int, UIEffect> dropEffectDict = new Dictionary<int, UIEffect>();
|
|
static PackModel _playerPack;
|
static PackModel playerPack
|
{
|
get { return _playerPack ?? (_playerPack = ModelCenter.Instance.GetModel<PackModel>()); }
|
}
|
|
static GuardModel guardModel { get { return ModelCenter.Instance.GetModel<GuardModel>(); } }
|
|
public static void Request(H0701_tagItemDrop h0701)
|
{
|
#if UNITY_EDITOR
|
string _content = string.Format("DropItemManager => 掉落物Id: dropID => {0}", h0701.DropID);
|
RuntimeLogUtility.AddLog_Blue(_content, PlayerDatas.Instance.PlayerId);
|
#endif
|
if (m_MapItemDict.ContainsKey(h0701.DropID))
|
{
|
Debug.LogErrorFormat("掉落物Id: {0} 已经存在与列表中, 是否出现bug?", h0701.DropID);
|
return;
|
}
|
|
JsonData _userData = JsonMapper.ToObject(h0701.UserData);
|
|
if (DungeonStage.CurrentMapType != MapType.OpenCountry
|
&& (_userData as IDictionary).Contains("4")
|
&& CrossServerUtility.IsCrossServer())
|
{
|
string _info = StringUtility.Contact(h0701.DropID, "|",
|
h0701.ItemTypeID, "|",
|
h0701.OwnerType, "|",
|
h0701.OwnerID);
|
#if UNITY_EDITOR
|
Debug.Log(_info);
|
#endif
|
}
|
|
if (((System.Collections.IDictionary)_userData).Contains("5"))
|
{
|
if ((int)_userData["5"] == 1)
|
{
|
if (h0701.OwnerType == 1)
|
{
|
if (h0701.OwnerID != PlayerDatas.Instance.PlayerId)
|
{
|
return;
|
}
|
}
|
else if (h0701.OwnerType == 2)
|
{
|
TeamModel _teamModel = ModelCenter.Instance.GetModel<TeamModel>();
|
if (_teamModel.myTeam.teamId != h0701.OwnerID)
|
{
|
return;
|
}
|
}
|
else if (h0701.OwnerType == 5)
|
{
|
if (PlayerDatas.Instance.baseData.faction != h0701.OwnerID)
|
{
|
return;
|
}
|
}
|
else if (h0701.OwnerType == 6)
|
{
|
bool _result = false;
|
JsonData _owners = _userData["3"];
|
for (int i = 0; i < _owners.Count; ++i)
|
{
|
if ((int)_owners[i] == PlayerDatas.Instance.PlayerId)
|
{
|
_result = true;
|
}
|
}
|
|
if (!_result)
|
{
|
return;
|
}
|
}
|
}
|
}
|
|
Vector3 _dropPosition = new Vector3((h0701.PosX - GA_Hero.MapOffset.x) * .5f, 0, (h0701.PosY - GA_Hero.MapOffset.z) * .5f);
|
RaycastHit _hitInfo;
|
if (Physics.Raycast(_dropPosition + new Vector3(0, 30, 0), Vector3.down, out _hitInfo, 100, LayerUtility.WalkbleMask))
|
{
|
_dropPosition = _hitInfo.point;
|
}
|
|
DropItem _item = DropItem.Drop((int)h0701.ItemTypeID, _dropPosition, CameraController.Instance.CameraObject);
|
DropObject _dropObject = new DropObject
|
{
|
dropItem = _item,
|
ownerID = h0701.OwnerID,
|
dropID = h0701.DropID,
|
itemID = (int)h0701.ItemTypeID,
|
ownerType = h0701.OwnerType,
|
remainTime = h0701.RemainTime * Constants.F_GAMMA
|
};
|
|
if (DungeonStage.CurrentMapType != MapType.OpenCountry
|
&& (_userData as IDictionary).Contains("4")
|
&& CrossServerUtility.IsCrossServer())
|
{
|
string _info = StringUtility.Contact(h0701.DropID, "|",
|
h0701.ItemTypeID, "|",
|
h0701.OwnerType, "|",
|
h0701.OwnerID, "|",
|
_dropPosition);
|
#if UNITY_EDITOR
|
Debug.Log(_info);
|
#endif
|
}
|
|
if (h0701.UserDataLen > 2)
|
{
|
_dropObject.userData = _userData;
|
}
|
|
m_MapItemDict.Add(h0701.DropID, _dropObject);
|
m_MapItemIdList.Add(h0701.DropID);
|
instanceIdToItemId[h0701.DropID] = (int)h0701.ItemTypeID;
|
intstanceIdToPosition[h0701.DropID] = _dropPosition;
|
}
|
|
public static bool HandupTryGetHeroItem(out DropObject dropObject)
|
{
|
try
|
{
|
dropObject = null;
|
int _dropID;
|
int _itemID;
|
|
GA_Hero _hero = PlayerDatas.Instance.hero;
|
|
m_MapItemIdList.Sort((i1, i2) =>
|
{
|
float _checkDist1 = 10000;
|
if (m_MapItemDict.ContainsKey(i1))
|
{
|
_checkDist1 = MathUtility.DistanceSqrtXZ(_hero.Pos, m_MapItemDict[i1].dropItem.transform.position);
|
}
|
|
float _checkDist2 = 10000;
|
if (m_MapItemDict.ContainsKey(i2))
|
{
|
_checkDist2 = MathUtility.DistanceSqrtXZ(_hero.Pos, m_MapItemDict[i2].dropItem.transform.position);
|
}
|
|
if (_checkDist1 < _checkDist2)
|
{
|
return 1;
|
}
|
else if (_checkDist1 > _checkDist2)
|
{
|
return -1;
|
}
|
|
return 0;
|
});
|
|
for (int i = m_MapItemIdList.Count - 1; i >= 0; --i)
|
{
|
_dropID = m_MapItemIdList[i];
|
|
if (m_MapItemDict.ContainsKey(_dropID))
|
{
|
if (CheckCanPickUp(m_MapItemDict[_dropID], false))
|
{
|
_itemID = (int)m_MapItemDict[_dropID].itemID;
|
|
if (SettingEffectMgr.Instance.GetSettingEffect())
|
{
|
if (CheckCanPickUp(m_MapItemDict[_dropID], false))
|
{
|
dropObject = m_MapItemDict[_dropID];
|
return true;
|
}
|
}
|
else
|
{
|
dropObject = m_MapItemDict[_dropID];
|
return true;
|
}
|
}
|
}
|
}
|
|
return false;
|
}
|
catch (Exception ex)
|
{
|
DebugEx.Log(ex);
|
dropObject = null;
|
return false;
|
}
|
|
}
|
|
private static float s_ChkPickupInterval;
|
|
public static void Update()
|
{
|
if (Time.time - s_ChkPickupInterval > .5f)
|
{
|
GA_Hero _hero = PlayerDatas.Instance.hero;
|
if (_hero != null)
|
{
|
CheckPickupItem(_hero.Pos);
|
s_ChkPickupInterval = Time.time;
|
}
|
}
|
|
int _dropID;
|
|
for (int i = m_MapItemIdList.Count - 1; i >= 0; --i)
|
{
|
_dropID = m_MapItemIdList[i];
|
|
if (m_MapItemDict.ContainsKey(_dropID))
|
{
|
if (m_MapItemDict[_dropID].remainTime > 0)
|
{
|
m_MapItemDict[_dropID].remainTime -= Time.deltaTime;
|
if (m_MapItemDict[_dropID].remainTime < 0)
|
{
|
m_MapItemDict[_dropID].remainTime = 0;
|
}
|
}
|
}
|
}
|
}
|
|
public static bool TryGetItemIdFromInstanceId(int _instanceId, out int _itemId)
|
{
|
return instanceIdToItemId.TryGetValue(_instanceId, out _itemId);
|
}
|
|
public static bool TryGetDropPositionFromInstanceId(int _instanceId, out Vector3 _position)
|
{
|
return intstanceIdToPosition.TryGetValue(_instanceId, out _position);
|
}
|
|
public static void ReleaseClientID(int dropID)
|
{
|
if (m_MapItemIdList.Contains(dropID))
|
{
|
m_MapItemIdList.Remove(dropID);
|
}
|
}
|
|
public static void Release(int dropId)
|
{
|
#if UNITY_EDITOR
|
string _content = string.Format("DropItemManager => 清理掉落物Id: dropID => {0}", dropId);
|
RuntimeLogUtility.AddLog_Blue(_content, PlayerDatas.Instance.PlayerId);
|
#endif
|
|
if (m_MapItemDict.ContainsKey(dropId))
|
{
|
if (m_MapItemDict[dropId].dropItem)
|
{
|
#if UNITY_EDITOR
|
_content = string.Format("DropItemManager => |-- 正确执行了清理", dropId);
|
RuntimeLogUtility.AddLog_Red(_content, PlayerDatas.Instance.PlayerId);
|
#endif
|
DropItem.Reycle(m_MapItemDict[dropId].dropItem);
|
}
|
else
|
{
|
#if UNITY_EDITOR
|
_content = string.Format("DropItemManager => |-- 清理时对象不存在", dropId);
|
RuntimeLogUtility.AddLog_Red(_content, PlayerDatas.Instance.PlayerId);
|
#endif
|
}
|
m_MapItemDict.Remove(dropId);
|
instanceIdToItemId.Remove(dropId);
|
intstanceIdToPosition.Remove(dropId);
|
}
|
else
|
{
|
#if UNITY_EDITOR
|
_content = string.Format("DropItemManager => |-- 掉落无不存在: dropID => {0}", dropId);
|
RuntimeLogUtility.AddLog_Red(_content, PlayerDatas.Instance.PlayerId);
|
#endif
|
}
|
|
if (m_CacheTipErrorDict.ContainsKey(dropId))
|
{
|
m_CacheTipErrorDict.Remove(dropId);
|
}
|
|
ReleaseClientID(dropId);
|
}
|
|
public static void ReleaseAll()
|
{
|
for (int i = m_MapItemIdList.Count - 1; i >= 0; --i)
|
{
|
Release(m_MapItemIdList[i]);
|
}
|
m_CacheTipErrorDict.Clear();
|
}
|
|
public static void CheckPickupItem(Vector3 checkPosition)
|
{
|
// 挂机状态下
|
if (SettingEffectMgr.Instance.GetSettingEffect() && !UserInputHandler.isTouched)
|
{
|
// 不自动拾取则直接返回
|
if (HangUpSetModel.Instance.GetBool(HangUpAutoBoolType.isAutoDrop) == false)
|
{
|
return;
|
}
|
}
|
|
DropObject _item = null;
|
|
for (int i = m_MapItemIdList.Count - 1; i >= 0; --i)
|
{
|
if (m_MapItemDict.ContainsKey(m_MapItemIdList[i]) == false)
|
{
|
continue;
|
}
|
|
if (!CheckCanPickUp(m_MapItemDict[m_MapItemIdList[i]], false) && !UserInputHandler.isTouched)
|
{
|
continue;
|
}
|
|
_item = m_MapItemDict[m_MapItemIdList[i]];
|
|
Vector3 _disVec = _item.dropItem.transform.position - checkPosition;
|
_disVec.y = 0;
|
float _chkDis = Vector3.SqrMagnitude(_disVec);
|
|
if (_chkDis < 1f)
|
{
|
C0701_tagPickUpItem _proto = new C0701_tagPickUpItem();
|
_proto.MapItemID = (uint)m_MapItemIdList[i];
|
|
if (CrossServerUtility.IsCrossServer())
|
{
|
GameNetSystem.Instance.SendToCrossServer(_proto);
|
}
|
else
|
{
|
GameNetSystem.Instance.SendInfo(_proto);
|
}
|
|
//Debug.LogFormat("发送捡起物品: {0}的包", m_MapItemIdList[i]);
|
//ReleaseClientID(m_MapItemIdList[i]);
|
}
|
|
}
|
|
}
|
|
private static Dictionary<int, float> m_CacheTipErrorDict = new Dictionary<int, float>();
|
private static void TipOthersItem(int id, bool isNotify)
|
{
|
if (m_CacheTipErrorDict.ContainsKey(id))
|
{
|
if (Time.realtimeSinceStartup - m_CacheTipErrorDict[id] > 1)
|
{
|
m_CacheTipErrorDict[id] = Time.realtimeSinceStartup;
|
}
|
else
|
{
|
return;
|
}
|
}
|
if (isNotify)
|
{
|
SysNotifyMgr.Instance.ShowTip("OpenHazyRegionError_5");
|
}
|
}
|
|
private static bool CheckCanPickUp(DropObject dropObject, bool isNotify=true)
|
{
|
if (dropObject.ownerType == 1)
|
{
|
if (dropObject.ownerID != PlayerDatas.Instance.PlayerId)
|
{
|
TipOthersItem(dropObject.dropID, isNotify);
|
return false;
|
}
|
}
|
else if (dropObject.ownerType == 2)
|
{
|
TeamModel _teamModel = ModelCenter.Instance.GetModel<TeamModel>();
|
if (_teamModel.myTeam.teamId != dropObject.ownerID)
|
{
|
TipOthersItem(dropObject.dropID, isNotify);
|
return false;
|
}
|
}
|
else if (dropObject.ownerType == 5)
|
{
|
if (PlayerDatas.Instance.baseData.faction != dropObject.ownerID)
|
{
|
TipOthersItem(dropObject.dropID, isNotify);
|
return false;
|
}
|
}
|
else if (dropObject.ownerType == 6)
|
{
|
bool _result = false;
|
JsonData _owners = dropObject.userData["3"];
|
for (int i = 0; i < _owners.Count; ++i)
|
{
|
if ((int)_owners[i] == PlayerDatas.Instance.PlayerId)
|
{
|
_result = true;
|
}
|
}
|
|
if (!_result)
|
{
|
TipOthersItem(dropObject.dropID, isNotify);
|
return false;
|
}
|
}
|
else if (dropObject.ownerType == 7)
|
{
|
if (dropObject.ownerID != PlayerDatas.Instance.baseData.FamilyId)
|
{
|
TipOthersItem(dropObject.dropID, isNotify);
|
return false;
|
}
|
}
|
|
ItemConfig _itemModel = ItemConfig.Get(dropObject.itemID);
|
|
// 背包已满,且不是铜钱不拾取
|
if (playerPack.GetEmptyGridCount(PackType.Item) == 0
|
&& _itemModel.Type != (int)ItemType.DropCopper
|
&& _itemModel.Type != (int)ItemType.Copper)
|
{
|
return false;
|
}
|
|
// 判断是否处于挂机状态, 不是的话不判断设置信息
|
if (PlayerDatas.Instance.hero != null)
|
{
|
if (PlayerDatas.Instance.hero.aiHandler.IsAuto()
|
&& !HangUpSetModel.Instance.GetBool(HangUpAutoBoolType.isAutoDrop))
|
{
|
return false;
|
}
|
|
// 对装备是否拾取的判断
|
if (PlayerDatas.Instance.IsEquip((ItemType)_itemModel.Type))
|
{
|
//Debug.LogFormat("检测装备: {0} 是否可以拾取, 颜色: {1}", _itemModel.ID, (E_ItemColor)_itemModel.ItemColor);
|
// 是否配置了白色,蓝色装备不捡
|
if (HangUpSetModel.Instance.GetBool(HangUpAutoBoolType.whiteEquip)
|
&& (_itemModel.ItemColor == (int)E_ItemColor.White
|
|| _itemModel.ItemColor == (int)E_ItemColor.Blue))
|
{
|
//Debug.Log(" |-- 配置了白色/蓝色不拾取, 这个是白色/蓝色的, 不拾取");
|
return true;
|
}
|
|
// 是否配置了紫色装备不捡
|
if (HangUpSetModel.Instance.GetBool(HangUpAutoBoolType.purpleEquip)
|
&& _itemModel.ItemColor >= (int)E_ItemColor.Purple)
|
{
|
//Debug.Log(" |-- 配置了紫色以上不拾取, 这个是紫色以上的, 不拾取");
|
return true;
|
}
|
}
|
// 项链或者仙器
|
else if (
|
((ItemType)_itemModel.Type == ItemType.Equip_FairyCan1
|
|| (ItemType)_itemModel.Type == ItemType.Equip_FairyCan2
|
|| (ItemType)_itemModel.Type == ItemType.Equip_Jade
|
|| (ItemType)_itemModel.Type == ItemType.Equip_Neck)
|
&& HangUpSetModel.Instance.GetBool(HangUpAutoBoolType.necklaces))
|
{
|
//Debug.Log(" |-- 配置了项链或者仙器不拾取, 这个是项链或者仙器, 不拾取");
|
return true;
|
}
|
// 宝石
|
else if ((ItemType)_itemModel.Type == ItemType.Gemstone
|
&& HangUpSetModel.Instance.GetBool(HangUpAutoBoolType.gem))
|
{
|
//Debug.Log(" |-- 配置了项链或者仙器不拾取, 这个是项链或者仙器, 不拾取");
|
return true;
|
}
|
// 药品(改贵重物品)
|
else if (Array.IndexOf(GeneralDefine.ImportantItemType, _itemModel.Type) >= 0
|
&& Array.IndexOf(GeneralDefine.ImportantItemID, _itemModel.ID) >= 0
|
&& HangUpSetModel.Instance.GetBool(HangUpAutoBoolType.drug))
|
{
|
return true;
|
}
|
// 金币
|
else if ((ItemType)_itemModel.Type == ItemType.DropCopper
|
&& HangUpSetModel.Instance.GetBool(HangUpAutoBoolType.coins))
|
{
|
return true;
|
}
|
else if (((ItemType)_itemModel.Type == ItemType.Equip_Neck
|
|| (ItemType)_itemModel.Type == ItemType.Equip_FairyCan1
|
|| (ItemType)_itemModel.Type == ItemType.Equip_FairyCan2
|
|| (ItemType)_itemModel.Type == ItemType.Equip_Jade)
|
&& HangUpSetModel.Instance.GetBool(HangUpAutoBoolType.necklaces))
|
{
|
return true;
|
}
|
// 其他
|
else
|
{
|
if ((ItemType)_itemModel.Type != ItemType.DropCopper
|
&& (ItemType)_itemModel.Type != ItemType.Drugs
|
&& (ItemType)_itemModel.Type != ItemType.Gemstone
|
&& !PlayerDatas.Instance.IsEquip((ItemType)_itemModel.Type)
|
// 以上类型都不是且开启了其他拾取的时候
|
&& HangUpSetModel.Instance.GetBool(HangUpAutoBoolType.other))
|
{
|
return true;
|
}
|
}
|
}
|
|
return false;
|
}
|
|
#region 守护拾取
|
public static bool TryGetGuardPickUpItem(Vector3 position, ref List<int> dropRefItemList)
|
{
|
for (int i = 0; i < m_MapItemIdList.Count; i++)
|
{
|
if (CheckCanGuardPickUp(position, guardModel.pickUpViewRange, i))
|
{
|
dropRefItemList.Add(m_MapItemIdList[i]);
|
}
|
}
|
return dropRefItemList.Count > 0;
|
}
|
|
public static bool CheckCanGuardPickUp(Vector3 position)
|
{
|
for (int i = 0; i < m_MapItemIdList.Count; i++)
|
{
|
if (CheckCanGuardPickUp(position, guardModel.pickUpViewRange, i))
|
{
|
return true;
|
}
|
}
|
return false;
|
}
|
|
public static void CheckGuardPickUpItem(Vector3 position)
|
{
|
guardSendPickList.Clear();
|
for (int i = 0; i < m_MapItemIdList.Count; i++)
|
{
|
if (guardSendedItemDict.ContainsKey(m_MapItemIdList[i]))
|
{
|
var guardDropItem = guardSendedItemDict[m_MapItemIdList[i]];
|
var t = DateTime.Now - guardDropItem.sendTime;
|
if (t.TotalSeconds > 3)
|
{
|
guardSendedItemDict.Remove(m_MapItemIdList[i]);
|
}
|
else
|
{
|
continue;
|
}
|
}
|
|
if (CheckCanGuardPickUp(position, guardModel.pickUpAreaRange, i))
|
{
|
guardSendPickList.Add((ushort)m_MapItemIdList[i]);
|
Vector3 _pos = Vector3.zero;
|
if (TryGetDropPositionFromInstanceId(m_MapItemIdList[i], out _pos))
|
{
|
GuardDropItem guardDropItem = new GuardDropItem();
|
guardDropItem.dropItemPos = _pos;
|
guardDropItem.sendTime = DateTime.Now;
|
guardSendedItemDict.Add(m_MapItemIdList[i], guardDropItem);
|
}
|
}
|
}
|
if (guardSendPickList.Count > 0)
|
{
|
CA312_tagCMGuardPickupItem _proto = new CA312_tagCMGuardPickupItem();
|
_proto.MapItemID = guardSendPickList.ToArray();
|
_proto.ItemCount = (ushort)_proto.MapItemID.Length;
|
|
if (CrossServerUtility.IsCrossServer())
|
{
|
GameNetSystem.Instance.SendToCrossServer(_proto);
|
}
|
else
|
{
|
GameNetSystem.Instance.SendInfo(_proto);
|
}
|
}
|
}
|
|
private static Dictionary<int, GuardDropItem> guardSendedItemDict = new Dictionary<int, GuardDropItem>();
|
private static List<ushort> guardSendPickList = new List<ushort>();
|
private static List<Vector3> guardDropItemPosList = new List<Vector3>();
|
|
public struct GuardDropItem
|
{
|
public DateTime sendTime;
|
public Vector3 dropItemPos;
|
}
|
|
public static void GuardPickupItemSucc(ushort[] mapItemID)
|
{
|
guardDropItemPosList.Clear();
|
for (int i = 0; i < mapItemID.Length; i++)
|
{
|
if (guardSendedItemDict.ContainsKey(mapItemID[i]))
|
{
|
guardDropItemPosList.Add(guardSendedItemDict[mapItemID[i]].dropItemPos);
|
guardSendedItemDict.Remove(mapItemID[i]);
|
}
|
}
|
if (guardDropItemPosList.Count > 0)
|
{
|
guardPickupCallBack(guardDropItemPosList);
|
}
|
}
|
|
private static bool CheckCanGuardPickUp(Vector3 position, float _pickRange, int _itemIndex)
|
{
|
DropObject _item = null;
|
if (m_MapItemDict.ContainsKey(m_MapItemIdList[_itemIndex]) == false)
|
{
|
return false;
|
}
|
_item = m_MapItemDict[m_MapItemIdList[_itemIndex]];
|
if (_item != null && _item.ownerType == 7)//守护过滤归属为仙盟的类型
|
{
|
return false;
|
}
|
Vector3 _disVec = _item.dropItem.transform.position - position;
|
_disVec.y = 0;
|
float _chkDis = Vector3.SqrMagnitude(_disVec);
|
if (_chkDis > _pickRange)
|
{
|
return false;
|
}
|
|
// 如果是仙盟归属的, 设定为守护不拾取
|
if (_item.ownerType == 7)
|
{
|
return false;
|
}
|
|
return CheckCanPickUp(_item, false);
|
}
|
#endregion
|
|
}
|