Skip to content

RoleData

muxigame edited this page Nov 24, 2021 · 1 revision

角色数据 Role Data

$\textcolor{RedOrange}{GalForUnity.Model.RoleData : MonoBehaviour, IEnumerable<RoleData.RoleDataItem>}$

GalForUnity.Model.RoleData是角色数据的持有类,持有着角色数据,继承自MonoBehaviour和 IEnumerable<RoleData.RoleDataItem>,这表明他可以被forEach,此外这个类在不远的版本会被重写

功能

GalForUnity.Model.RoleData:角色数据是从1.0b集成过来的基础类,并且在1.0r中进行了重写,更新了UI展示,以及优化了内部结构。它继承自MonoBehavior,通常在使用RoleModel的时候被自动附加,用于保存角色数据,但也可作为PlotRequire的角色要求以及ActionModel的角色数值变更等。本身重载了大量方法,方便使用。

image-20210105214511876

在1.0b中,RoleData被设计用来满足我们的首款Gal,仅支持{"力量","灵感","节奏","运动","爱心","魅力","心情","潜能","好感度"}等数值。在最新1.0r版本中,可定义的数值不在受限,但是创建出来的默认名字会从上述数组中诞生,不要担心,您可以随意修改,这只是为了方便而已,在未来的版本中,默认数组也会允许修改!

字段

名称 描述
List dataArray 单条角色数据的列表,以提供高速的索引访问
Dictionary<string,RoleDataItem> _dataMap 单条角色数据的字典,以提供高速的名称访问
GalForUnity.Model.RoleData Data 这个字段主要用于字典与列表的同步访问后返回自身
string[] Names 角色所有数值的名称组成的数组
GalForUnity.Model.RoleModel RoleMode 角色模型的引用,如果角色模型(RoleModel)持有角色数据(RoleData),则该字段会被角色模型赋值

方法

名称 描述
RoleDataItem GetItem(string itemName) 根据数值名称获得单个角色数值项
RoleDataItem GetItem(int itemIndex) 根据数值索引获得单个角色数值项
RoleData SetData(string itemName, int value) 根据数值名称设置单个角色数值项
RoleData SetData(int index, int value) 根据数值索引设置单个角色数值项
int Size() 获取当前角色数据中数据项的个数
List GetData() 获得所有的角色数据项,并返回列表
bool Equals(object x) 比较与另一个RoleData的数据是否相等
int GetHashCode 获得哈希值
IEnumerator GetEnumerator() 获得迭代器
IEnumerator IEnumerable.GetEnumerator() 获得迭代器
operator == 比较与另一个RoleData的数据是否相等
operator != 比较与另一个RoleData的数据是否不相等
operator >= 比较一个RoleData是否大于另一个RoleData
operator <= 比较一个RoleData是否小于另一个RoleData
this[string empty] 允许通过数据名称访问角色数值
this[intempty] 允许通过索引访问角色数值

源代码

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using GalForUnity.System;
using GalForUnity.System.Event;
using UnityEngine;

namespace GalForUnity.Model{
    /// <summary>
    /// 角色数据,角色数据存放的类,保存着玩家定义的角色数据
    /// </summary>
    public class RoleData : MonoBehaviour, IEnumerable<RoleData.RoleDataItem>{
        /// <summary>
        /// 某一项角色数据
        /// </summary>
        [Serializable]
        public class RoleDataItem : ICloneable {
            public RoleDataItem(string name,int otherValue,int index){
                this.name = name;
                value = otherValue;
                this.index = index;
            }
            [SerializeField] public string name;
            [SerializeField] public int value;
            public int index;

            public object Clone(){
                return new RoleDataItem(name,value,index);
            }
        }
        

        [SerializeField] public List<RoleDataItem> dataArray;
        private readonly Dictionary<string,RoleDataItem> _dataMap = new Dictionary<string, RoleDataItem>();

        public RoleData Data{
            get{
                if (_dataMap.Count != dataArray.Count){
                    _dataMap.Clear();
                    for (var i = 0; i < dataArray.Count; i++){
                        dataArray[i].index = i;
                        _dataMap.Add(dataArray[i].name,dataArray[i]);
                    }
                }
                return this;
            }
        }

        // ReSharper disable all MemberCanBePrivate.Global
        public RoleDataItem GetItem(string itemName){
            return Data._dataMap[itemName];
        }

        public RoleDataItem GetItem(int itemIndex){
            return Data.dataArray[itemIndex];
        }
        /// <summary>
        /// 获得所有的属性名
        /// </summary>
        public string[] Names{
            get{
                return Data._dataMap.Keys.ToArray();
            }
        }
        

        [NonSerialized] public RoleModel RoleModel = null;


        public int Size(){
            return dataArray.Count;
        }

        public List<RoleDataItem> GetData(){
            return dataArray;
        }

        public RoleData SetData(string itemName, int value){
            this[itemName] = value;
            EventCenter.GetInstance().RoleChangeEvent.Invoke(_dataMap[itemName].index, itemName, value);
            EventCenter.GetInstance().RoleStateChangeEvent.Invoke(RoleModel);
            return this;
        }

        public RoleData SetData(int index, int value){
            this[index] = value;
            EventCenter.GetInstance().RoleChangeEvent.Invoke(index, Names[index], value);
            EventCenter.GetInstance().RoleStateChangeEvent.Invoke(RoleModel);
            return this;
        }
        

        /// <summary>
        /// 比较和某个角色的属性是否相等
        /// </summary>
        /// <param name="x">要进行比较的其他角色</param>
        /// <returns>返回和某个角色的属性是否相等</returns>
        public override bool Equals(object x){
            switch (x){
                case null:
                    return ReferenceEquals(this, null);
                case RoleData otherRoleData:
                    return Array.Equals(otherRoleData, dataArray.ToArray());
                default:
                    return false;
            }
        }

        public override int GetHashCode(){
            return base.GetHashCode();
        }
        /// <summary>
        /// 获得迭代器的方法
        /// </summary>
        /// <returns>迭代器</returns>
        public IEnumerator<RoleDataItem> GetEnumerator(){
            
            return new RoleDateEnumerator(dataArray);
        }
        /// <summary>
        /// 获得迭代器的方法
        /// </summary>
        /// <returns>迭代器</returns>
        IEnumerator IEnumerable.GetEnumerator(){
            return new RoleDateEnumerator(dataArray);
        }


        public static bool operator ==(RoleData roleModel, RoleData roleModel1){
            return RoleData.Equals(roleModel, roleModel1);
        }
        public RoleData Parse(List<RoleDataItem> roleDataItems){
            foreach (var roleDataItem in roleDataItems){
                this[roleDataItem.index] = roleDataItem.value;
            }
            return this;
        }
        public static List<RoleDataItem> operator +(RoleData roleModel, RoleData roleModel1){
            var min = roleModel.Size() < roleModel1.Size() ? roleModel.Data.dataArray : roleModel1.Data.dataArray;
            var max= roleModel.Size() > roleModel1.Size() ? roleModel.Data._dataMap : roleModel1.Data._dataMap;
            Dictionary<string, RoleDataItem> newData = max.Clone();
            foreach (var roleItem in min){
                if(!newData.ContainsKey(roleItem.name)) throw new ArgumentException();
                newData[roleItem.name].value += roleItem.value;
            }
            return newData.Values.ToList();
        } 
        public static List<RoleDataItem> operator -(RoleData roleModel, RoleData roleModel1){
            var min = roleModel.Size() < roleModel1.Size() ? roleModel.Data.dataArray : roleModel1.Data.dataArray;
            var max= roleModel.Size() > roleModel1.Size() ? roleModel.Data._dataMap : roleModel1.Data._dataMap;
            Dictionary<string, RoleDataItem> newData = max.Clone();
            foreach (var roleItem in min){
                if(!newData.ContainsKey(roleItem.name)) throw new ArgumentException();
                newData[roleItem.name].value -= roleItem.value;
            }
            return newData.Values.ToList();
        }

        public static bool operator !=(RoleData roleModel, RoleData roleModel1){
            return !(roleModel == roleModel1);
        }

        public static bool operator >=(RoleData maxRoleModel, RoleData minRoleModel1){
            if (maxRoleModel.Size() < minRoleModel1.Size()) return false;
            for (int i = 0, length = minRoleModel1.dataArray.Count; i < length; i++){
                if (maxRoleModel[minRoleModel1.Names[i]] < minRoleModel1[i]) return false;
            }

            return true;
        }

        public static bool operator <=(RoleData minRoleModel, RoleData maxRoleModel1){
            if (minRoleModel.Size() > maxRoleModel1.Size()) return false;
            for (int i = 0, length = minRoleModel.dataArray.Count; i < length; i++){
                if (maxRoleModel1[minRoleModel.Names[i]] < minRoleModel[i]) return false;
            }

            return true;
        }

        /// <summary>
        /// 返回角色的数值,如果不存在,返回最小值;
        /// </summary>
        /// <param name="empty">角色的属性名</param>
        /// <exception cref="ArgumentException">当尝试设置的属性名为空时,触发异常</exception>
        public int this[string empty]{
            get{
                if (!Data._dataMap.ContainsKey(empty)){
                    return _dataMap[empty].value;
                }
                throw new ArgumentException();
                //return Int32.MinValue; //如果不存在,返回最小值;
            }
            set{
                if (!Data._dataMap.ContainsKey(empty)){
                    _dataMap[empty].value = value;
                    dataArray[_dataMap[empty].index].value = value;
                    return;
                }
                throw new ArgumentException();
            }
        }
        /// <summary>
        /// 返回角色的数值,如果不存在,返回最小值;
        /// </summary>
        /// <param name="empty">角色的属性名</param>
        /// <exception cref="ArgumentOutOfRangeException">当尝试设置的属性名为空时,触发异常</exception>
        public int this[int empty]{
            get{
                if (Data.dataArray.Count>empty){
                    return dataArray[empty].value;
                }
                throw new ArgumentOutOfRangeException();
            }
            set{
                dataArray[empty].value = value;
                _dataMap[dataArray[empty].name].value = value;
            }
        }
        /// <summary>
        /// 角色数据的迭代器
        /// </summary>
        private sealed class RoleDateEnumerator : ICloneable, IEnumerator<RoleDataItem>{
            private List<RoleDataItem> _roleDataItems;
            private int _index = -1;
            private RoleDataItem _currentRoleDataItem;

            public RoleDateEnumerator(List<RoleDataItem> roleDataItems){
                this._roleDataItems = roleDataItems;
            }

            public bool MoveNext(){
                if (_index < _roleDataItems.Count){
                    _currentRoleDataItem = _roleDataItems[++_index];
                    return true;
                }

                _index = _roleDataItems.Count;
                return false;
            }

            public void Reset(){
                _index = -1;
                _currentRoleDataItem = null;
            }

            public RoleDataItem Current{
                get{
                    if (_index == -1){
                        throw new ArgumentOutOfRangeException();
                    }

                    if (_index >= _roleDataItems.Count){
                        throw new ArgumentOutOfRangeException();
                    }

                    return _currentRoleDataItem;
                }
            }

            object IEnumerator.Current => Current;

            public object Clone(){
                return this.MemberwiseClone();
            }

            public void Dispose(){
                if (_roleDataItems != null){
                    _roleDataItems.Clear();
                    _roleDataItems = null;
                }

                _currentRoleDataItem = null;
                _index = -1;

            }
        }


    }

}

Clone this wiki locally