// *********************************************************************** // Assembly : Game // Author : Kimch // Created : 2021-03-26 // Description : // Last Modified By : // Last Modified On : // *********************************************************************** // // // *********************************************************************** using CodeStage.AntiCheat.ObscuredTypes; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace G { /// /// /// public class PetProxy : F.GameProxy { public class PetInfo { /// /// /// public readonly ItemPet item; public readonly PetSkillInfo mainSkill; public readonly List skills = new List(); /// /// /// ItemPetLevel currLevelItem => ItemProxy.Instance.GetStaticItem(grade); /// /// id /// public int id => item.id; /// /// /// public string name { get { var saveName = ArchiveProxy.Instance.GetString(this.id); if (!string.IsNullOrEmpty(saveName)) return saveName; return item.name; } set { ArchiveProxy.Instance.SetString(this.id, value); } } /// /// /// public string[] icon { get { return item.icon; } } private ObscuredInt _friend = -1; /// /// /// public int friend { get => _friend; private set { _friend = value; } } private ObscuredInt _friendMax = 0; /// /// /// public int friendMax { get { return _friendMax; } private set { _friendMax = value; } } /// /// /// public int friendId { get { return item.active[0]; } } /// /// /// /// public bool AddFriend(int value) { if (isUnlock) { friend += value; bool result = isFriend; SaveLocal(); return result; } return false; } /// /// 已结交 /// public bool isFriend { get { if (grade > 0) return true; if (isUnlock && friend >= friendMax) { grade = 1; MissionProxy.Instance.OnEvent(MissionProxy.解锁宠物数量); return true; } return false; } } /// /// /// public bool isUnlock { get { if (this.friend >= 0) { return true; } else { var mission = MissionProxy.Instance.GetMission(item.unlock); if (mission != null && mission.isCompleted) { this.friend = 0; return true; } return false; } } } /// /// /// public string unlockText { get { var mission = MissionProxy.Instance.GetMission(item.unlock); if (mission != null) { return mission.description; } return ""; } } /// /// /// public ItemAccess access { get { return ItemProxy.Instance.GetStaticItem(item.access); } } private ObscuredInt _grade = 0; /// /// 等级 /// public int grade { get { return _grade; } private set { if (value <= gradeMax && value != grade) { _grade = value; attributes.Clear(); var sources = item.attributes; if (sources != null) for (int i = 0; i < sources.Length; i++) { attributes.Add(new CombatAttribute { id = (CombatAttributeId)sources[i][0], value = sources[i][1] + value * sources[i][2], }); } } } } /// /// 等级上限 /// public int gradeMax { get; private set; } /// /// /// public bool isMaxGrade => grade >= gradeMax; /// /// /// /// /// public bool AddGrade(int value) { bool result = true; int tmpGrade = this.grade + value; int tmpGradeMax = this.gradeMax; if (tmpGrade > tmpGradeMax) { tmpGrade = tmpGradeMax; } this.grade = tmpGrade; SaveLocal(); MissionProxy.Instance.OnEvent(MissionProxy.宠物升级次数); return result; } private ObscuredInt _exp = 0; /// /// /// public int exp { get { return _exp; } private set { _exp = value; } } /// /// /// public int expMax { get { var levelItem = this.currLevelItem; return levelItem != null ? levelItem.exp : 1; } } /// /// /// /// /// public bool AddExp(int value) { bool result = false; int tmpExp = this.exp + value; int tmpExpMax = this.expMax; int tmpLevel = this.grade; if (tmpExp >= tmpExpMax) { tmpExp -= tmpExpMax; tmpLevel += 1; result = true; } this.exp = tmpExp; this.grade = tmpLevel; SaveLocal(); MissionProxy.Instance.OnEvent(MissionProxy.宠物升级次数); return result; } /// /// 伤害 /// public int damage { get; set; } /// /// 速度 /// public float speed { get { return item.speed * 0.001f; } } /// /// /// public int splash => item.splash; /// /// /// public int bullet => item.bullet; /// /// /// public float bulletDamage { get { if (grade > 0) return currLevelItem.damage * 0.01f; return item.damage * 0.01f; } } /// /// /// public float bulletSpeed { get { if (grade > 0) return currLevelItem.bulletSpeed * 0.001f; return item.bulletSpeed * 0.001f; } } /// /// /// public int bulletNumber { get { if (grade > 0) return currLevelItem.bulletNumber; return item.bulletNumber; } } /// /// /// public int bulletLayer { get { return item.bulletLayer; } } /// /// /// public int combatValue { get { int result = item.combatValue; int tmpGrade = this.grade; if (tmpGrade > 0) { var levelItem = this.currLevelItem; if (levelItem != null) result += levelItem.combatValue; for (int i = 0; i < attributes.Count; i++) { var attr = attributes[i]; result += attr.combatValue; } } for (int i = 0; i < skills.Count; i++) { if (skills[i] != null && tmpGrade >= i * 10) result += skills[i].combatValue; } return result; } } /// /// /// public readonly List attributes = new List(); /// /// 出战中 /// public bool isBattling { get { return this == PetProxy.Instance.battlePet; } set { PetProxy.Instance.battlePet = value ? this : null; } } public PetInfo(ItemPet petItem) { this.item = petItem; friendMax = petItem.active[1]; gradeMax = ItemProxy.Instance.GetStaticItems().Count; if (petItem.mainSkills != null) mainSkill = new PetSkillInfo(ItemProxy.Instance.GetStaticItem(petItem.mainSkills[0])); for (int i = 0; i < petItem.skills.Length; i++) { var petSkillItem = ItemProxy.Instance.GetStaticItem(petItem.skills[i]); skills.Add(new PetSkillInfo(petSkillItem)); } LoadLocal(); } /// /// /// /// /// public void Set(int level, int exp) { this.grade = level; this.exp = exp; MissionProxy.Instance.OnEvent(MissionProxy.解锁宠物数量); SaveLocal(); } /// /// /// public void Reset() { grade = 0; exp = 0; } /// /// /// /// public bool Active() { return AddFriend(friendMax); } /// /// /// /// public int Upgrade() { if (grade > 0 && grade < gradeMax) { var up = AddExp(100); if (up) { Instance.UpdateAttributes(true); } return up ? 2 : 1; } return 0; } public IList CheckSkill() { var tmpGrade = this.grade; for (int i = 0; i < skills.Count; i++) { skills[i].grade = tmpGrade < i * 10 ? i * 10 : 0; } return skills; } /// /// /// /// public bool CheckUpgrade() { if (this.isFriend) { var costs = CalcUpgradeCost(); return MoneyProxy.Instance.CheckMoney(costs); } return false; } static readonly Item.ItemInfo[] _UpgradeCost = new Item.ItemInfo[0]; public IList CalcUpgradeCost() { //_UpgradeCost[0].Set(20, grade / 10 + 1); //_UpgradeCost[1].Set(1, grade * 100); return _UpgradeCost; } /// /// /// public Item.ItemInfo recastCostLow { get { var petConst = ItemProxy.Instance.GetStaticItem(1); var cost = petConst.recastCostInfo1; cost.count = item.skills.Length; return cost; } } /// /// /// public Item.ItemInfo recastCostHigh { get { var petConst = ItemProxy.Instance.GetStaticItem(1); var cost = petConst.recastCostInfo2; cost.count = item.skills.Length; return cost; } } /// /// /// /// public bool CheckRecast() { return grade >= Mathf.Min(30, (skills.Count - 1) * 10); } /// /// /// public void ApplyRecast() { //防止错误 if (_RecastedPetSkills[0] == null) { return; } skills.Clear(); for (int i = 0; i < 8; i++) { if (_RecastedPetSkills[i] != null) { skills.Add(_RecastedPetSkills[i]); } } SaveLocal(); ResetRecast(); Instance.UpdateAttributes(true); } /// /// /// public void ResetRecast() { for (int i = 0; i < 8; i++) { _RecastedPetSkills[i] = null; } //int skillCount = skills.Count; //for (int i = 0; i < skillCount; i++) //{ // _RecastedPetSkills[i] = skills[i]; //} } /// /// /// public IList recastSkills { get { if (_RecastedPetSkills[0] == null) { return null; } return _RecastedPetSkills; } } static readonly PetSkillInfo[] _RecastedPetSkills = new PetSkillInfo[8]; /// /// /// /// public PetSkillInfo[] RecastSkills(bool high, bool[] lockFilter) { int skillCount = skills.Count; for (int i = 0; i < skillCount; i++) { if (_RecastedPetSkills[i] == null) { _RecastedPetSkills[i] = skills[i]; } } for (int i = 0; i < 8; i++) { if (!lockFilter[i]) _RecastedPetSkills[i] = null; } for (int i = 0; i < skillCount; i++) { if (_RecastedPetSkills[i] == null) { var rndSkill = GetRandomSkill(high, i); _RecastedPetSkills[i] = rndSkill; } } MissionProxy.Instance.OnEvent(MissionProxy.宠物技能洗练); return _RecastedPetSkills; } /// /// /// /// /// /// PetSkillInfo GetRandomSkill(bool high, int index) { var petConst = ItemProxy.Instance.GetStaticItem(1); var skillPool = high ? petConst.skillPool2 : petConst.skillPool1; if (skillPool.Length <= index) return null; int resultId = 0; int loop = 0; do { loop++; resultId = 0; int skillId = GlobalUtils.GetRandom(skillPool); for (int i = 0; i < 8; i++) { if (_RecastedPetSkills[i] != null && _RecastedPetSkills[i].id == skillId) { resultId = -1; break; } } if (resultId == 0) { resultId = skillId; } } while (resultId < 0 && loop < 1000); var petSkillItem = ItemProxy.Instance.GetStaticItem(resultId); return new PetSkillInfo(petSkillItem); } public int GetAttributes(List results) { if (grade > 0) { for (int i = 0; i < attributes.Count; i++) { var attr = attributes[i]; results.Add(attr); } } return this.combatValue; } void SaveLocal() { var dataList = ArchiveProxy.Instance.GetIntList(this.id); if (dataList != null) { dataList.Clear(); dataList.Add(friend); dataList.Add(grade); dataList.Add(exp); dataList.Add(skills.Count); for (int i = 0; i < skills.Count; i++) { dataList.Add(skills[i].id); } ArchiveProxy.Instance.SetIntList(this.id, dataList); } } void LoadLocal() { var dataList = ArchiveProxy.Instance.GetIntList(this.id); if (dataList != null && dataList.Count > 0) { int index = 0; friend = dataList[index++]; grade = dataList[index++]; exp = dataList[index++]; skills.Clear(); int skillCount = dataList.SafeGet(index++); for (int i = 0; i < skillCount; i++) { var skillItem = ItemProxy.Instance.GetStaticItem(dataList.SafeGet(index++)); if (skillItem != null) skills.Add(new PetSkillInfo(skillItem)); } } } } /// /// /// public class PetSkillInfo { public readonly ItemPetSkill item; /// /// /// public int id => item.id; /// /// /// public int combatValue => item.combatValue; public int grade { get; set; } public bool isUnlock => grade == 0; public PetSkillInfo(ItemPetSkill petSkillItem) { this.item = petSkillItem; } } #region Field /// /// 上战宠物 /// private int _battlePetId; /// /// /// readonly Dictionary _pets = new Dictionary(8); int _feedTimestamp; #endregion #region Property /// /// /// public PetInfo battlePet { get { _pets.TryGetValue(_battlePetId, out var result); return result; } set { _battlePetId = value != null ? value.item.id : 0; SaveLocal(); } } public int petFeedTimestamp => _feedTimestamp; /// /// /// public int combatValue => PlayerProxy.Instance.GetCombatValue(PlayerProxy.ATTRIBUTES_INDEX_PET); #endregion #region Method /// /// /// /// public IReadOnlyCollection GetAllPets() { return _pets.Values; } /// /// /// /// /// public PetInfo GetPet(int id) { _pets.TryGetValue(id, out var result); return result; } /// /// /// /// public int GetPetCombatValue() { return PlayerProxy.Instance.GetCombatValue(PlayerProxy.ATTRIBUTES_INDEX_PET); } /// /// /// /// /// public int UpgradePet(PetInfo pet, bool ad) { if (pet.isMaxGrade) { return 0; } if (ad) { int feedCount = TimeProxy.Instance.GetTimes(TimeProxy.宠物升级); if (feedCount <= 0) return 0; } int result = 1; if (pet.AddGrade(ad ? 2 : 1)) { result = 2; } if (ad) { TimeProxy.Instance.CostTimes(TimeProxy.宠物升级); } else { _feedTimestamp = Launch.Timestamp + 60 * 60 * 8; } SaveLocal(); UpdateAttributes(true); return result; } public int GetRedPoint() { var remainTime = petFeedTimestamp - Launch.Timestamp; if (remainTime <= 0) { return 1; } //foreach (var pet in _pets.Values) //{ // if (pet.CheckUpgrade()) // { // return 1; // } //} return 0; } public void UpdateAttributes(bool sendNotification) { int combatValue = 0; var results = F.ListPool.Get(); foreach (var pet in _pets.Values) { if (pet != null && pet.isFriend) { combatValue += pet.GetAttributes(results); } } PlayerProxy.Instance.UpdatePetCombatValue(results, combatValue, sendNotification); F.ListPool.Release(results); } const string ARCHIVE_KEY = "pet"; const string ARCHIVE_KEY_V1 = "pet_v1"; /// /// /// private void LoadLocal() { var petItems = ItemProxy.Instance.GetStaticItems(); _pets.Clear(); for (int i = 0; i < petItems.Count; i++) { var petItem = petItems[i]; _pets.Add(petItem.id, new PetInfo(petItem)); } var dataList = ArchiveProxy.Instance.GetIntList(ARCHIVE_KEY_V1); if (dataList != null && dataList.Count > 0) { int index = 0; _battlePetId = dataList[index++]; _feedTimestamp = dataList.SafeGet(index++); } else { dataList = ArchiveProxy.Instance.GetIntList(ARCHIVE_KEY); if (dataList != null && dataList.Count > 0) { int index = 0; dataList.SafeGet(index++); int petLevel = dataList.SafeGet(index++); int petExp = dataList.SafeGet(index++); if (petLevel > 0) { _pets[12000].Set(petLevel, 0); } else if (petExp > 0) { _pets[12000].Set(1, 0); } } } ArchiveProxy.Instance.RemoveIntList(ARCHIVE_KEY); UpdateAttributes(false); } /// /// /// private void SaveLocal() { var dataList = ArchiveProxy.Instance.GetIntList(ARCHIVE_KEY_V1); if (dataList != null) { dataList.Clear(); dataList.Add(_battlePetId); dataList.Add(_feedTimestamp); ArchiveProxy.Instance.SetIntList(ARCHIVE_KEY_V1, dataList); } } #endregion #region Unity && Proxy public static PetProxy Instance { get { return GetInstance(); } } public override void LoadCompleted() { } public override void ReadArchive() { LoadLocal(); } #endregion } }