using System; using System.Collections.Generic; using Logic.Action; using UnityEngine; using Logic.Multilingual; using RuntimeData; using UnityEngine.Serialization; //Data Asset用到,绝对不能修改顺序! public enum TechType { None = 0, Climbing = 1, Meditation = 2, Mining = 3, Philosophy = 4, Smithery = 5, Organization = 6, Strategy = 7, Farming = 8, Diplomacy = 9, Construction = 10, Riding = 11, FreeSpirit = 12, Chivalry = 13, Roads = 14, Trade = 15, Hunting = 16, Forestry = 17, Archery = 18, Mathematics = 19, Spiritualism = 20, Fishing = 21, Ramming = 22, Sailing = 23, Aquatism = 24, Navigation = 25, EgyptFlandre = 26, EgyptRemilia = 27, EgyptMeiling = 28, EgyptPatchouli = 29, EgyptSakuya = 30, //Kaguya新增 KaguyaHunting = 31, KaguyaArcher = 32, KaguyaSpiritual = 33, KaguyaForestry = 34, KaguyaMath = 35, KaguyaRoad = 36, KaguyaTrade = 37, KaguyaConstruction = 38, //Remilia新增 NoUseRemiliaConstruction = 39, RemiliaFarming = 40, NoUseRemiliaAuatism = 41, RemiliaRamming = 42, NoUseRemiliaChivalry = 43, RemiliaFreeSpirit = 44, //Kanako KanakoClimbing = 45, KanakoMeditation = 46, KanakoMining = 47, KanakoPhilosophy = 48, KanakoSmithery = 49, KanakoRiding = 50, KanakoFreeSpirit = 51, KanakoChivalry = 52, KanakoRoads = 53, KanakoTrade = 54, KanakoNavigation = 55, //KomeijiEmpire KomeijiIndianMuladhara =56, //跟轮,初始科技 KomeijiIndianArchery = 57,KomeijiIndianMethematics =58, KomeijiIndianSailing = 60,KomeijiIndianNavigation = 61, KomeijiIndianRiding = 62,KomeijiIndianChivalry = 64 } //Data Asset用到,绝对不能修改顺序! public enum TechAtom { None = 0, //None科技12个 UnitActionUpgrade = 1, UnitActionRecover = 2, UnitActionExamine = 3, UnitActionCapture = 4, TrainUnitWarrior = 5, BuildWonderPEACE = 6, BuildWonderKNOWLEDGE = 7, BuildWonderTRADE = 8, BuildWonderWEALTH = 9, BuildWonderPOWER = 10, BuildWonderPARK = 11, BuildWonderEYE = 12 , //Climbing UnitSkillMOUNTAINMOVE = 13, UnitSkillMOUNTAINDEFENSE = 14, //Climbing BuildAcademy =15, StartWonderPEACE =16, BuildMine = 17, StartWonderKNOWLEDGE = 18, TechIndustry = 19, TrainUnitMinder = 20, TrainUnitSwordsman = 21, BuildForge = 22, GainFruit = 23, TrainUnitDefender = 24, TechAlly = 25, BuildFarm = 26, TechEmbassy = 27, TechDiplomacySight, TrainUnitCloak, BuildWindmill, BurnForest, TrainUnitRider, BuildMilitary, Disband, BuildRoad, BuildBridge, StartWonderTRADE, TrainUnitKnights, Destroy, BuildMarket, StartWonderWEALTH, GainAnimal, BuildLumberHut, ClearForest, TrainUnitArcher, UnitSkillFORESTDEFENSE, BuildSawmill, TrainUnitCatapult, BuildPreserve, GrowForest, GainFish, BuildPort, UnitSkillWATERMOVE, BuildNavalBase, TrainUnitRammerShip, TrainUnitShip, UnitSkillOCEANMOVE, UnitSkillWATERDEFENSE, UnitSkillOCEANDEFENSE, TrainUnitBomberShip, UnitActionGather, KaguyaFrenchNapoleanic_DECAY,//这个废弃了 TrainUnitKaguyaFrenchAnimalWarrior, UnitSkillKaguyaFrenchWarriorSynergy, KaguyaFrenchNapoleonicCode, GrowForestOutside, BuildKaguyaFrenchYard, UnitSkillKaguyaFrenchCatapultSynergy, KaguyaFrenchBambooMove, //RemiliaForces BuildEgyptianIrrigation, BuildRemiliaMilitary, UnitSkillRemiliaForcesKill, BuildEgyptianWaterIrrigation, RedMistDefense, //KanakoForces 新增 CreateMountain, AcademyCreateMountain, CreateMountainPro, GainMetal, BuildMetalStation, TrainUnitMoriyaRider, BuildMoriyaMilitary, TrainUnitMoriyaKnight, MoriyaRoad, CreateMountainWater, //奇观补漏 StartWonderPOWER, StartWonderPARK, StartWonderEYE, //阵营巨人补漏 TrainUnitKoakuma, TrainUnitFrenchWolf, TrainUnitHebi, //KomeijiEmpire KomeijiIndianDharma,//正法 KomeijiIndianAgni,//地脉 KomeijiIndianSevenRiver,//七河之地 TrainUnitKomeijiArcher, TrainUnitKomeijiCatapult, TrainUnitKomeijiBomberShip, TrainUnitKomeijiShip, TrainUnitKomeijiRider, TrainUnitKomeijiKnight, TrainUnitKomeijiFairyBigGuy, BuildCityWall, } [Serializable] [CreateAssetMenu(fileName = "TechDataAssets", menuName = "TH1 Game Data/Tech Data Asset")] public class TechDataAssets : ScriptableObject { public List TechList = new List(); public List TechAtomList = new List(); [NonSerialized] private bool _initialized; private Dictionary _techInfoDict = new Dictionary(); [NonSerialized] private bool _atomInit; private Dictionary _techAtomInfoDict = new Dictionary(); [NonSerialized] private bool _nextTechCacheInit; private Dictionary> _nextTechCache = new Dictionary>(); private void Init() { if (_initialized) return; foreach (var tech in TechList) _techInfoDict.Add(tech.TechType,tech); _initialized = true; } //-------------------------------------- TechInfo相关 -------------------------------- public TechInfo GetTechInfo(TechType techType) { Init(); return _techInfoDict.GetValueOrDefault(techType); } public bool GetTechInfo(TechType techType,out TechInfo info) { Init(); return _techInfoDict.TryGetValue(techType, out info); } public bool GetTechDesc(TechType techType, out string ret) { Init(); ret = ""; if (_techInfoDict.TryGetValue(techType, out var info)) { ret = info.Description; return true; } return false; } // 获取科技的所有后继科技 (非伟人科技) public HashSet GetNextTechs(TechType techType) { BuildNextTechCache(); if (!_nextTechCache.TryGetValue(techType, out var cached)) { return new HashSet(); } return new HashSet(cached); } // 获取科技的所有后继科技(无GC版本,结果写入调用方提供的set) public void GetNextTechsNonAlloc(TechType techType, HashSet result) { if (result == null) return; result.Clear(); BuildNextTechCache(); if (!_nextTechCache.TryGetValue(techType, out var cached)) return; foreach (var t in cached) result.Add(t); } // 获取科技的后继科技 public bool GetNextTechs(TechType techType, HashSet set) { bool isFound = false; //遍历所有科技 foreach (var techInfo in TechList) { //如果已经在set 跳过 if (set.Contains(techInfo.TechType)) continue; //如果他的父亲不在set里,跳过 if (!techInfo.FatherInSet(set)) continue; //剩下的一定是父亲在set里,或者父亲就是后继树根节点(techType)的节点,加入set set.Add(techInfo.TechType); isFound = true; } return isFound; } private void BuildNextTechCache() { if (_nextTechCacheInit) return; Init(); _nextTechCache.Clear(); foreach (var tech in TechList) { var set = new HashSet { tech.TechType }; while (GetNextTechs(tech.TechType, set)) { } set.Remove(tech.TechType); _nextTechCache[tech.TechType] = set; } _nextTechCacheInit = true; } //-------------------------------------- TechAtomInfo相关 -------------------------------- private void AtomInit() { if (_atomInit) return; foreach (var techAtomInfo in TechAtomList) _techAtomInfoDict.Add(techAtomInfo.TechAtom,techAtomInfo); _atomInit = true; } public bool GetTechAtomInfo(TechAtom techAtom, out TechAtomInfo info ) { AtomInit(); return _techAtomInfoDict.TryGetValue(techAtom,out info); } } //判断当前的TechAtomIcon在处理View时的类型(根据类型会分开处理尺寸之类的) public enum IconViewSizeType { Building,Unit,_256x256,Defense,Resource,Ground,MountainBuilding } [Serializable] public class TechAtomInfo { public TechAtom TechAtom; [MultilingualField] public string TechAtomName; [MultilingualField] public string Desc; //是否是生产unit的时候AddSkill的技能 public bool IsAddSkill; public List AddSkillCondition; public SkillType AddSkillType; public bool EnableAction; public List TechActions; public bool UseActionSprite; public SpriteContainer IconContainer; [FormerlySerializedAs("TechAtomIconViewType")] public IconViewSizeType iconViewSizeType; public Sprite GetIcon(CivEnum civEnum,ForceEnum forceEnum,GridSpType gridSpType = GridSpType.None,int level = 0) { //如果使用Action的Icon if (EnableAction && UseActionSprite && TechActions.Count > 0) { if (!Table.Instance.ActionDataAssets.GetActionInfo(TechActions[0], out var info)) return null; return info.GetIcon(Table.Instance.TransCivEnumToCivId(civEnum),Table.Instance.TransForceEnumToForceId(forceEnum),gridSpType); } //如果使用自身的Icon return IconContainer.GetIcon(civEnum, forceEnum, gridSpType, level); } public bool CheckCondition(UnitFullType unitFullType) { if(AddSkillCondition.Count == 0) return true; foreach (var t in AddSkillCondition) if (unitFullType.Equals(t)) return true; return false; } } [Serializable] public class TechInfo { public TechType TechType; // 唯一ID [MultilingualField] public string TechName; // 显示名称 [MultilingualField] public string Description; // 描述 public Sprite icon; // 图标 public int CostLevel; // 消耗等级(1,2,3) public List FatherTechList; //public List techActions; // 解锁action public List TechAtomList; // 解锁actionAtom public TechTreeCircleViewType TechTreeCircleViewType; public bool FatherInSet(HashSet set) { foreach (var tech in FatherTechList) if (set.Contains(tech)) return true; return false; } public bool IsFather(TechType techType) { foreach(var tech in FatherTechList) if (tech == techType) return true; return false; } public List GetActionList() { var actionList = new List(); foreach (var t in this.TechAtomList) { if (!Table.Instance.TechDataAssets.GetTechAtomInfo(t, out var info)) continue; if (info.EnableAction) foreach(var p in info.TechActions) actionList.Add(p); } return actionList; } public int GetTechAtomCount() { return TechAtomList.Count; } }