649 lines
19 KiB
C#
649 lines
19 KiB
C#
//**********************************************//
|
|
//作者:#何健#
|
|
//日期:#2016.10.14#
|
|
//简述:#背包的模型,主要是一些数据#
|
|
//*********************************************//
|
|
using System.Collections.Generic;
|
|
using Thousandto.Cfg.Data;
|
|
using Thousandto.Code.Global;
|
|
using Thousandto.Core.Base;
|
|
using UnityEngine;
|
|
using System;
|
|
using Thousandto.Code.Center;
|
|
|
|
namespace Thousandto.Code.Logic
|
|
{
|
|
/// <summary>
|
|
/// 类BackPackModel说明
|
|
/// </summary>
|
|
public class ItemContianerModel
|
|
{
|
|
#region//常量
|
|
//背包空格数量警告
|
|
public const int BAG_SPACE_COUNT_WARNNING = 10;
|
|
#endregion
|
|
|
|
#region //私有变量
|
|
private int _allCount; //总格子数
|
|
private int _openedCount; //已经打开的格子数
|
|
private Dictionary<ulong, ItemBase> _itemsOfUid; //uid
|
|
private Dictionary<int, ItemBase> _itemsOfIndex; //位置
|
|
private ContainerType _containerType; //容器类型
|
|
private int _nowOpenIndex; //正在开启的格子下标
|
|
private float _useTime; //使用的时间
|
|
private int _remainSpaceCount = 0; //格子的剩余数量
|
|
private bool _isInitializing = false; //是否正在初始化背包
|
|
private Dictionary<int, long> _itemCounts;//物品数量字典,用于存储物品数量以便使用
|
|
#endregion
|
|
|
|
#region //属性
|
|
public int AllCount
|
|
{
|
|
get
|
|
{
|
|
return _allCount;
|
|
}
|
|
set
|
|
{
|
|
_allCount = value;
|
|
}
|
|
}
|
|
|
|
public int OpenedCount
|
|
{
|
|
get
|
|
{
|
|
return _openedCount;
|
|
}
|
|
set
|
|
{
|
|
_openedCount = value;
|
|
UpdateRemainCount();
|
|
}
|
|
}
|
|
|
|
public Dictionary<ulong, ItemBase> ItemsOfUID
|
|
{
|
|
get
|
|
{
|
|
return _itemsOfUid;
|
|
}
|
|
set
|
|
{
|
|
_itemsOfUid = value;
|
|
}
|
|
}
|
|
|
|
public Dictionary<int, ItemBase> ItemsOfIndex
|
|
{
|
|
get
|
|
{
|
|
return _itemsOfIndex;
|
|
}
|
|
set
|
|
{
|
|
_itemsOfIndex = value;
|
|
}
|
|
}
|
|
|
|
public int NowOpenIndex
|
|
{
|
|
get
|
|
{
|
|
return _nowOpenIndex;
|
|
}
|
|
set
|
|
{
|
|
_nowOpenIndex = value;
|
|
}
|
|
}
|
|
|
|
public float UseTime
|
|
{
|
|
get
|
|
{
|
|
return _useTime;
|
|
}
|
|
set
|
|
{
|
|
_useTime = value;
|
|
}
|
|
}
|
|
|
|
public ContainerType ContainerType
|
|
{
|
|
get
|
|
{
|
|
return _containerType;
|
|
}
|
|
set
|
|
{
|
|
_containerType = value;
|
|
}
|
|
}
|
|
public int RemainSpaceCount
|
|
{
|
|
get { return _remainSpaceCount; }
|
|
}
|
|
|
|
//是否正在初始化
|
|
public bool IsInitializing
|
|
{
|
|
get { return _isInitializing; }
|
|
set { _isInitializing = value; }
|
|
}
|
|
public Dictionary<int, long> ItemCounts
|
|
{
|
|
get
|
|
{
|
|
return _itemCounts;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region//公共接口
|
|
|
|
public ItemContianerModel()
|
|
{
|
|
_allCount = 0;
|
|
_openedCount = 0;
|
|
_itemsOfIndex = new Dictionary<int, ItemBase>(200);
|
|
_itemsOfUid = new Dictionary<ulong, ItemBase>(200);
|
|
_itemCounts = new Dictionary<int, long>(200);
|
|
_useTime = 0;
|
|
_nowOpenIndex = 0;
|
|
}
|
|
/// <summary>
|
|
/// 根据DBID 获取物品信息
|
|
/// </summary>
|
|
/// <param name="uid"></param>
|
|
/// <returns></returns>
|
|
public T GetItemByUID<T>(ulong uid) where T : ItemBase
|
|
{
|
|
ItemBase ret = null;
|
|
ItemsOfUID.TryGetValue(uid, out ret);
|
|
return ret as T;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据物品在容器的位置来获取物品信息
|
|
/// </summary>
|
|
/// <param name="index"></param>
|
|
/// <returns></returns>
|
|
public T GetItemByIndex<T>(int index) where T : ItemBase
|
|
{
|
|
ItemBase ret = null;
|
|
ItemsOfIndex.TryGetValue(index, out ret);
|
|
return ret as T;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据物品ID获取物品 ,获取容器的第一个。
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public T GetItemByID<T>(int id) where T : ItemBase
|
|
{
|
|
ItemBase ret = null;
|
|
var eumerater = ItemsOfUID.GetEnumerator();
|
|
try
|
|
{
|
|
while (eumerater.MoveNext())
|
|
{
|
|
if (eumerater.Current.Value.CfgID == id)
|
|
{
|
|
ret = eumerater.Current.Value;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
eumerater.Dispose();
|
|
}
|
|
return ret as T;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取容器中所有为id的物品信息
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public List<T> GetItemListByCfgID<T>(int cfgId) where T : ItemBase
|
|
{
|
|
List<T> ret = new List<T>(ItemsOfUID.Count);
|
|
var eumerater = ItemsOfUID.GetEnumerator();
|
|
try
|
|
{
|
|
while (eumerater.MoveNext())
|
|
{
|
|
if (eumerater.Current.Value.CfgID == cfgId)
|
|
{
|
|
ret.Add(eumerater.Current.Value as T);
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
eumerater.Dispose();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 根据物品类型获取物品列表
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="type"></param>
|
|
/// <returns></returns>
|
|
public List<T> GetItemListByType<T>(int type) where T : ItemBase
|
|
{
|
|
List<T> ret = new List<T>(ItemsOfUID.Count);
|
|
var eumerater = ItemsOfUID.GetEnumerator();
|
|
try
|
|
{
|
|
while (eumerater.MoveNext())
|
|
{
|
|
var retItem = eumerater.Current.Value as T;
|
|
if (retItem == null)
|
|
continue;
|
|
if (type != ItemType.UnDefine)
|
|
{
|
|
if (eumerater.Current.Value.Type == type)
|
|
ret.Add(retItem);
|
|
}
|
|
else
|
|
{
|
|
if (eumerater.Current.Value.Type != ItemType.Equip && eumerater.Current.Value.Type != ItemType.ImmortalEquip)
|
|
ret.Add(retItem);
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
eumerater.Dispose();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取容器中所有物品
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public List<T> GetItemList<T>() where T : ItemBase
|
|
{
|
|
List<T> ret = new List<T>(ItemsOfUID.Count);
|
|
var eumerater = ItemsOfUID.GetEnumerator();
|
|
try
|
|
{
|
|
while (eumerater.MoveNext())
|
|
{
|
|
var item = eumerater.Current.Value as T;
|
|
if (null != item)
|
|
{
|
|
ret.Add(item);
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
eumerater.Dispose();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据物品的大类型获取物品的列表
|
|
/// </summary>
|
|
/// <param name="type"></param>
|
|
/// <returns></returns>
|
|
public List<ItemBase> GetItemListByItemBigType(ItemBigType type)
|
|
{
|
|
List<ItemBase> ret = null;
|
|
switch (type)
|
|
{
|
|
case ItemBigType.UnDefine:
|
|
case ItemBigType.All:
|
|
{
|
|
ret = GetItemList<ItemBase>();
|
|
}
|
|
break;
|
|
case ItemBigType.Equip:
|
|
{
|
|
ret = GetItemListByType<ItemBase>(ItemType.Equip);
|
|
}
|
|
break;
|
|
case ItemBigType.ImmortalEquip:
|
|
{
|
|
ret = GetItemListByType<ItemBase>(ItemType.ImmortalEquip);
|
|
}
|
|
break;
|
|
case ItemBigType.Other:
|
|
{
|
|
ret = GetItemListByType<ItemBase>(ItemType.UnDefine);
|
|
}
|
|
break;
|
|
}
|
|
ListSort(ret, true);
|
|
return ret;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据物品的大类型获取某个位置的物品
|
|
/// </summary>
|
|
/// <param name="type"></param>
|
|
/// <returns></returns>
|
|
public ItemBase GetItemByBigTypeAndIndex(ItemBigType type, int index)
|
|
{
|
|
if (index < 0 || index >= ItemsOfUID.Count)
|
|
return null;
|
|
var eumerater = ItemsOfUID.GetEnumerator();
|
|
try
|
|
{
|
|
int indexCounter = -1;
|
|
while (eumerater.MoveNext())
|
|
{
|
|
switch (type)
|
|
{
|
|
case ItemBigType.All:
|
|
{
|
|
++indexCounter;
|
|
}
|
|
break;
|
|
case ItemBigType.Equip:
|
|
{
|
|
if (eumerater.Current.Value.Type == ItemType.Equip)
|
|
{
|
|
++indexCounter;
|
|
}
|
|
}
|
|
break;
|
|
case ItemBigType.ImmortalEquip:
|
|
{
|
|
if (eumerater.Current.Value.Type == ItemType.ImmortalEquip)
|
|
{
|
|
++indexCounter;
|
|
}
|
|
}
|
|
break;
|
|
case ItemBigType.Other:
|
|
{
|
|
if (eumerater.Current.Value.Type != ItemType.Equip && eumerater.Current.Value.Type != ItemType.ImmortalEquip)
|
|
{
|
|
++indexCounter;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (indexCounter == index)
|
|
{
|
|
return eumerater.Current.Value;
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
eumerater.Dispose();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据物品的大列表获取物品的字典容器
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="type"></param>
|
|
/// <returns></returns>
|
|
public Dictionary<int, T> GetItemDicByItemBigType<T>(ItemBigType type) where T : ItemBase
|
|
{
|
|
Dictionary<int, T> itemDic = new Dictionary<int, T>();
|
|
var iter = _itemsOfIndex.GetEnumerator();
|
|
try
|
|
{
|
|
while (iter.MoveNext())
|
|
{
|
|
if (iter.Current.Value is T)
|
|
{
|
|
itemDic[iter.Current.Key] = iter.Current.Value as T;
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
iter.Dispose();
|
|
}
|
|
return itemDic;
|
|
}
|
|
|
|
//获取非绑定的物品
|
|
public Dictionary<int, T> GetUnBoundItems<T>(ItemBigType type) where T : ItemBase
|
|
{
|
|
Dictionary<int, T> itemDic = new Dictionary<int, T>();
|
|
|
|
var iter = _itemsOfIndex.GetEnumerator();
|
|
try
|
|
{
|
|
while (iter.MoveNext())
|
|
{
|
|
if (iter.Current.Value.IsBind == false)
|
|
{
|
|
itemDic[iter.Current.Key] = iter.Current.Value as T;
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
iter.Dispose();
|
|
}
|
|
return itemDic;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新物品信息,如果物品不存在则为创建新的,如果存在则会修改原来的值,由于没有多线程考虑,所以不会出现问题。
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <returns></returns>
|
|
public int UpdateItem(ItemBase item)
|
|
{
|
|
try
|
|
{
|
|
ItemBase oldItem = null;
|
|
if (ItemsOfIndex.TryGetValue(item.Index, out oldItem))
|
|
{
|
|
var dbId = oldItem.DBID;
|
|
ItemsOfIndex.Remove(item.Index);
|
|
ItemsOfUID.Remove(dbId);
|
|
ChangeCount(oldItem.CfgID, -oldItem.Count);
|
|
}
|
|
ItemsOfIndex.Add(item.Index, item);
|
|
ItemsOfUID.Add(item.DBID, item);
|
|
ChangeCount(item.CfgID, item.Count);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
|
|
}
|
|
|
|
return item.Index;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 删除物品
|
|
/// </summary>
|
|
/// <param name="uid">物品的唯一ID</param>
|
|
/// <returns></returns>
|
|
public void DeleteItem(ulong uid)
|
|
{
|
|
if (ItemsOfUID.ContainsKey(uid))
|
|
{
|
|
var item = ItemsOfUID[uid];
|
|
ChangeCount(item .CfgID, -item.Count);
|
|
ItemsOfIndex.Remove(item.Index);
|
|
ItemsOfUID.Remove(uid);
|
|
}
|
|
}
|
|
|
|
//清空数据
|
|
public void Clear()
|
|
{
|
|
ItemsOfIndex.Clear();
|
|
ItemsOfUID.Clear();
|
|
ItemCounts.Clear();
|
|
}
|
|
|
|
public int GetNewImmortalEquipIndex()
|
|
{
|
|
int index = 1;
|
|
for (int i = 1; i <= AllCount; i++)
|
|
{
|
|
if (!ItemsOfIndex.ContainsKey(i))
|
|
{
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
return index;
|
|
}
|
|
|
|
public void SortBag()
|
|
{
|
|
var list = new List<ItemBase>();
|
|
var e = ItemsOfIndex.GetEnumerator();
|
|
while (e.MoveNext())
|
|
{
|
|
list.Add(e.Current.Value);
|
|
}
|
|
ItemsOfIndex.Clear();
|
|
for (int i = 0; i < list.Count; i++)
|
|
{
|
|
list[i].Index = i + 1;
|
|
ItemsOfIndex.Add(i + 1, list[i]);
|
|
}
|
|
}
|
|
|
|
//根据配置id获取数量
|
|
public long GetCountByCfgId(int cfgId)
|
|
{
|
|
long result = 0;
|
|
ItemCounts.TryGetValue(cfgId, out result);
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
#region //私有方法
|
|
|
|
/// <summary>
|
|
/// 获取除装备和材质之外的物品
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
private List<T> GetOtherItems<T>() where T : ItemBase
|
|
{
|
|
List<T> ret = new List<T>(ItemsOfUID.Count);
|
|
var eunmerater = ItemsOfUID.GetEnumerator();
|
|
try
|
|
{
|
|
while (eunmerater.MoveNext())
|
|
{
|
|
if (eunmerater.Current.Value.Type != ItemType.Material && eunmerater.Current.Value.Type != ItemType.Equip)
|
|
{
|
|
var item = eunmerater.Current.Value as T;
|
|
if (null != item)
|
|
{
|
|
ret.Add(item);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
eunmerater.Dispose();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
//更新剩余数量
|
|
private void UpdateRemainCount()
|
|
{
|
|
var newCnt = _openedCount - _itemsOfIndex.Count;
|
|
if (_remainSpaceCount != newCnt)
|
|
{
|
|
//只针对背包进行更新
|
|
if (_containerType == Global.ContainerType.ITEM_LOCATION_BAG)
|
|
{
|
|
if (_remainSpaceCount < newCnt)
|
|
{
|
|
_remainSpaceCount = newCnt;
|
|
//空格增加
|
|
GameCenter.PushFixEvent((int)LogicEventDefine.EID_EVENT_WARINGBACKPACKCHANGE, false);
|
|
|
|
}
|
|
else
|
|
{
|
|
if (!IsInitializing)
|
|
{
|
|
_remainSpaceCount = newCnt;
|
|
//空格减少
|
|
GameCenter.PushFixEvent((int)LogicEventDefine.EID_EVENT_WARINGBACKPACKCHANGE, true);
|
|
}
|
|
else
|
|
{
|
|
if (newCnt < BAG_SPACE_COUNT_WARNNING)
|
|
{
|
|
_remainSpaceCount = newCnt;
|
|
GameCenter.PushFixEvent((int)LogicEventDefine.EID_EVENT_WARINGBACKPACKCHANGE, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_remainSpaceCount = newCnt;
|
|
}
|
|
}
|
|
|
|
private static int SortAsc(ItemBase left, ItemBase right)
|
|
{
|
|
return left.Index.CompareTo(right.Index);
|
|
}
|
|
|
|
//改变数量计数器
|
|
private void ChangeCount(int cfgId, long count)
|
|
{
|
|
long curCount = 0;
|
|
ItemCounts.TryGetValue(cfgId, out curCount);
|
|
curCount += count;
|
|
if(curCount < 0)
|
|
{
|
|
curCount = 0;
|
|
}
|
|
ItemCounts[cfgId] = curCount;
|
|
}
|
|
private static int SortDesc(ItemBase left, ItemBase right)
|
|
{
|
|
return right.Index.CompareTo(left.Index);
|
|
}
|
|
/// <summary>
|
|
/// 对列表进行排序
|
|
/// </summary>
|
|
/// <param name="field">对要排序的item的字段</param>
|
|
/// <param name="rule">排序规则</param>
|
|
public static void ListSort(List<ItemBase> list, bool isAsc)
|
|
{
|
|
if (list != null)
|
|
{
|
|
if (isAsc)
|
|
{
|
|
list.Sort(SortAsc);
|
|
}
|
|
else
|
|
{
|
|
list.Sort(SortDesc);
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|