// *********************************************************************** // Assembly : Game // Author : Kimch // Created : 2020-12-08 // Description : // Last Modified By : // Last Modified On : // *********************************************************************** // // // *********************************************************************** using System.Collections; using System.Collections.Generic; using UnityEngine; namespace G { /// /// /// public class LevelProxy : F.GameProxy { /// /// 关卡信息 /// public struct LevelInfo { public readonly ItemLevel item; /// /// /// public int id => item.id; public LevelInfo(ItemLevel item) { this.item = item; } public bool isCompleted { get => item.isCompleted; set => item.isCompleted = value; } } #region Field private int _lastHighestCompletedLevel; private int _maxLevel; private readonly List _normalLevels = new List(); private readonly List _endlessLevels = new List(); private readonly List _climbLevels = new List(); #endregion #region Property /// /// /// public int maxLevelId { get { return _maxLevel; } } /// /// /// public int maxChapterId { get { return 0; } } /// /// 当前章节 /// public int currentChapterId { get; private set; } /// /// /// public ItemChapter currentChapterItem { get { var result = ItemProxy.Instance.GetStaticItem(currentChapterId); return result ?? ItemProxy.Instance.GetStaticItem(1); } } /// /// 最大关 /// public int currentUnlockedLevel { get; private set; } /// /// 最大关(完成) /// public int currentCompletedLevel { get => ArchiveProxy.Instance.GetInt(GlobalDefine.KEY_MAX_COMPLETED_LEVEL_ID); private set { ArchiveProxy.Instance.SetInt(GlobalDefine.KEY_MAX_COMPLETED_LEVEL_ID, value); SyncLevel(value); } } public ItemLevel currentCompletedLevelItem { get { return ItemProxy.Instance.GetStaticItem(currentCompletedLevel); } } /// /// 新通关关卡 /// public int newCompletedLevel { get { int completedLevel = this.currentCompletedLevel; var result = completedLevel != _lastHighestCompletedLevel; if (result) _lastHighestCompletedLevel = completedLevel; return result ? _lastHighestCompletedLevel : 0; } } /// /// 最大无尽关卡 每周清版 /// public int highestEndlessStage { get { return ArchiveProxy.Instance.GetInt(GlobalDefine.KEY_MAX_ENDLESS_LEVEL_STAGE); } private set { ArchiveProxy.Instance.SetInt(GlobalDefine.KEY_MAX_ENDLESS_LEVEL_STAGE, value); } } /// /// /// public Item.ItemInfo highestEndlessRewards { get { return GetEndlessRewards(highestEndlessStage); } } /// /// /// public ItemLevel endlessLevel { get { if (_endlessLevels.Count > 0) return _endlessLevels[0].item; return ItemProxy.Instance.GetStaticItem(10000); } } /// /// /// public int endlessLevelRemainSeconds { get { var now5 = Launch.ServerNow.AddHours(-5).Date; var target5 = now5.AddDays(7 - ((6 + (int)now5.DayOfWeek) % 7)).AddHours(5); return (int)(target5 - Launch.ServerNow).TotalSeconds; } } #endregion #region Method /// /// /// /// /// public int GetCurrentChapterBoxId(int index) { var chapterItem = this.currentChapterItem; if (chapterItem != null && chapterItem.shopBox != null && index < chapterItem.shopBox.Length) return chapterItem.shopBox[index]; return 0; } /// /// /// /// /// public int GetCurrentLevelBoxId(int index) { var levelItem = this.currentCompletedLevelItem; if (levelItem != null && levelItem.shopBox != null && index < levelItem.shopBox.Length) return levelItem.shopBox[index]; return 0; } /// /// /// /// private void SyncLevel(int value) { this.currentUnlockedLevel = Mathf.Clamp(value + 1, 1, _maxLevel); var unlockLevelItem = ItemProxy.Instance.GetStaticItem(currentUnlockedLevel); if (unlockLevelItem != null) { this.currentChapterId = unlockLevelItem.chapterId; } } /// /// 完成关卡 /// /// public bool CompleteLevel(int levelId, int stageIndex) { var levelItem = ItemProxy.Instance.GetStaticItem(levelId); if (levelItem != null) { if (levelItem.type == 1) { if (!levelItem.isCompleted) { levelItem.isCompleted = true; if (this.currentCompletedLevel < levelId) { this.currentCompletedLevel = levelId; } SaveLevels(); MissionProxy.Instance.OnEvent(MissionProxy.通关成功, 1, levelId); PostNotification(GlobalDefine.EVENT_LEVEL_COMPLETED, levelId); return true; } else { MissionProxy.Instance.OnEvent(MissionProxy.通关成功, 1, levelId); return false; } } else if (levelItem.type == 2) { if (highestEndlessStage < stageIndex) { highestEndlessStage = stageIndex; SaveLevels(); } RankingProxy.Instance.UploadEndless(highestEndlessStage); return true; } else if (levelItem.type == 3) { return true; } } return false; } /// /// /// /// /// public void RestartLevel() { GlobalVar.EnterLevelFactor = 0; GameScene.Instance.EnterScene(GlobalVar.EnterLevelId); } /// /// /// /// public bool LoadPlayingLevelState() { GlobalVar.EnterLevelId = 0; GlobalVar.EnterStageIndex = 0; var results = GlobalVar.SavePlayingStateData; results.Clear(); var dataBytes = CodeStage.AntiCheat.Storage.ObscuredPrefs.GetByteArray("bt_state"); if (dataBytes != null && dataBytes.Length > 0) { using (var stream = new System.IO.MemoryStream(dataBytes)) { using (var reader = new System.IO.BinaryReader(stream)) { GlobalVar.EnterLevelId = reader.ReadInt32(); GlobalVar.EnterStageIndex = reader.ReadInt32(); int dataCount = reader.ReadInt32(); for (int i = 0; i < dataCount; i++) { results.Add(reader.ReadInt32()); } string content = null; if (GlobalVar.EnterLevelId > 0 && GlobalVar.EnterLevelId < 10000) { content = $"上次挑战第{GlobalVar.EnterLevelId}关未完成,是否继续?"; } else { content = $"上次挑战武道会第{GlobalVar.EnterStageIndex}关未完成,是否继续?"; } UI.MessageBox.ShowMessage("提示", content, "放弃", "继续", () => RemovePlayingLevelState(), () => RestartLevel()); } } return true; } return false; } /// /// /// /// /// /// public void SavePlayingLevelState(int levelId, int stageIndex, List data) { using (var stream = new System.IO.MemoryStream()) { using (var writer = new System.IO.BinaryWriter(stream)) { writer.Write(levelId); writer.Write(stageIndex); writer.Write(data.Count); for (int i = 0; i < data.Count; i++) { writer.Write(data[i]); } CodeStage.AntiCheat.Storage.ObscuredPrefs.SetByteArray("bt_state", stream.ToArray()); CodeStage.AntiCheat.Storage.ObscuredPrefs.Save(); } } } /// /// /// public void RemovePlayingLevelState() { GlobalVar.EnterLevelId = 0; GlobalVar.EnterStageIndex = 0; GlobalVar.SavePlayingStateData.Clear(); CodeStage.AntiCheat.Storage.ObscuredPrefs.DeleteKey("bt_state"); CodeStage.AntiCheat.Storage.ObscuredPrefs.Save(); } /// /// /// /// public int AgainStartLevel() { return StartLevel(GlobalVar.EnterLevelId); } /// /// /// public void FirstLevel() { GlobalVar.EnterLevelId = 1; GlobalVar.EnterStageIndex = 0; GlobalVar.EnterLevelFactor = 0; GameScene.Instance.EnterScene(GlobalVar.EnterLevelId); } /// /// /// /// public int StartLevel() { return StartLevel(currentUnlockedLevel); } public void StartActicityLevel(int id) //进入限时活动关卡 { GlobalVar.EnterLevelId = id; GlobalVar.EnterStageIndex = 0; GlobalVar.EnterLevelFactor = 0; GameScene.Instance.EnterScene(GlobalVar.EnterLevelId); } /// /// /// /// /// public int StartLevel(int id) { int result = CheckStartLevel(); if (result == 0) { GlobalVar.EnterLevelId = id; GlobalVar.EnterStageIndex = 0; GlobalVar.EnterLevelFactor = 0; AntiCheatProxy.Instance.CheckCheat(OnStartLevelCallback); } return result; } /// /// /// /// private void OnStartLevelCallback(int error, string message) { if (error == ErrorCode.TIME_CHEAT) { PostNotification(GlobalDefine.EVENT_SHOW_TOAST, "请检查手机时间"); return; } PlayerProxy.Instance.UseEnergyForLevel(); GameScene.Instance.EnterScene(GlobalVar.EnterLevelId); } /// /// /// /// private int CheckStartLevel() { if (!PlayerProxy.Instance.CheckEnergyForLevel()) { return 2; } if (BagProxy.Instance.BagIsFull()) { return 1; } return 0; } /// /// 扫荡 /// /// /// public int SweepLevel(int levelId) { int result = CheckStartLevel(); if (result == 0) { GlobalVar.EnterLevelId = levelId; GlobalVar.EnterStageIndex = 0; AntiCheatProxy.Instance.CheckCheat(OnSweepLevelCallback); } return result; } /// /// 扫荡 /// private void OnSweepLevelCallback(int error, string message) { if (error == 1) { PostNotification(GlobalDefine.EVENT_SHOW_TOAST, "请检查手机时间"); return; } AdProxy.Instance.PlayAd("battle", "ad_instant_level", (err, msg) => { if (err == 0) { SweepLevelSettle(); } }); } /// /// /// private void SweepLevelSettle() { PlayerProxy.Instance.UseEnergyForLevel(); TimeProxy.Instance.CostTimes(TimeProxy.扫荡关卡); var battleResult = GetSweepResult(GlobalVar.EnterLevelId); KUIWindow.OpenWindow(battleResult); } /// /// /// /// /// private BattleResult GetSweepResult(int levelId, bool offline = false) { var curLevelItem = ItemProxy.Instance.GetStaticItem(levelId); var curStageIndex = 0; var maxStageIndex = curLevelItem.maxStage; var curChapterId = curLevelItem.chapterId; BattleResult battleResult = new BattleResult(); battleResult.applyStep = 0; battleResult.shortcut = true; battleResult.duration = 0; battleResult.success = true; battleResult.levelId = levelId; battleResult.stageIndex = maxStageIndex; battleResult.stageIndexMax = maxStageIndex; //battleResult.exp = curLevelItem.exp; var stageId = 0; int dropBoost = PlayerProxy.Instance.GetAttributeValue(CombatAttributeId.稀有装备掉落); //计算 while (curStageIndex < maxStageIndex) { if (curStageIndex == 0) { stageId = GlobalUtils.GetRandom(curLevelItem.startStage); curStageIndex = 1; } else if (curStageIndex < maxStageIndex - 1) { var lastStage = ItemProxy.Instance.GetStaticItem(stageId); stageId = GlobalUtils.GetRandom(lastStage.nextStages); if (stageId <= 0) { stageId = lastStage.id; } curStageIndex++; } else { if (curLevelItem.hasEnd) { stageId = GlobalUtils.GetRandom(curLevelItem.endStage); } else { var lastStage = ItemProxy.Instance.GetStaticItem(stageId); stageId = GlobalUtils.GetRandom(lastStage.nextStages); if (stageId <= 0) { stageId = lastStage.id; } } curStageIndex = maxStageIndex; } var currStage = ItemProxy.Instance.GetStaticItem(stageId); if (currStage != null) { var stageBoxId = 0; var boxes = curLevelItem.boxes; if (boxes != null && boxes.Length > 0 && curStageIndex > 0) { if (curStageIndex < boxes.Length) stageBoxId = boxes[curStageIndex]; else stageBoxId = boxes[boxes.Length - 1]; } var dropBox = BoxProxy.Instance.GetBoxInfo(stageBoxId); if (dropBox != null) { var tmpList = F.ListPool.Get(); tmpList.AddRange(dropBox.GetRndItems(dropBoost)); var extra = dropBox.GetExtraItem(); if (extra.id > 0) { tmpList.Add(extra); } for (int i = 0; i < tmpList.Count; i++) { int id = tmpList[i].id; int count = tmpList[i].count; if (id > 0) { var prop = ItemProxy.Instance.GetStaticItem(id); if (prop != null) { //装备 if (prop.isMoney) { battleResult.AddMoney(id, count); } else if (prop.isWeaponOrEquipment) { var equipment = BagProxy.Instance.NewEquipment(prop.id); if (equipment != null) battleResult.equipments.Add(equipment); } } } } F.ListPool.Release(tmpList); } } } if (offline) return battleResult; var battlePet = PetProxy.Instance.battlePet; if (battlePet != null) { int enemyCount = Random.Range(90, 180); if (battlePet.id == 13010) { battleResult.AddMoney(1, enemyCount * 10); Debug.Log("扫荡金币 " + enemyCount * 10); } else if (battlePet.id == 13020) { var dropBox = BoxProxy.Instance.GetBoxInfo(30000); if (dropBox != null) { int max = 3; for (int i = 0; i < enemyCount && max > 0; i++) { var gem = dropBox.GetRndItem(); if (gem.id > 0) { Debug.Log("扫荡宝石 " + gem.id); battleResult.AddProp(gem.id, 1); max--; } } } } } if (FunctionProxy.Instance.GetFunctionUnlock(FunctionProxy.FunctionId.文学)) { int chapterId = curChapterId; for (int i = 0; i < 3; i++) { var dropBook = BookProxy.Instance.DropBookByChapter(chapterId); if (dropBook != null) { battleResult.dropBookId = dropBook.id; Debug.Log("扫荡出书 " + dropBook.id); break; } } } return battleResult; } /// /// /// /// /// public void OfflineLevel(float overflow, Callback2 callback) { var levelId = Mathf.Max(1, currentCompletedLevel); var battleResult = GetSweepResult(levelId, true); battleResult.duration = (int)overflow; battleResult.callback = callback; KUIWindow.OpenWindow(battleResult); } #region 无尽 /// /// 开始武道会 /// /// public void StartEndless(bool restart = false) { #if UNITY_EDITOR Debug.Log("开始武道会"); #endif GlobalVar.EnterLevelId = 10000; GlobalVar.EnterLevelFactor = 0; if (!restart) { var tmpStateIndex = highestEndlessStage; if (tmpStateIndex > 1) tmpStateIndex = Mathf.Min((tmpStateIndex - 1) / 10 * 10 + 1, 101); else tmpStateIndex = 1; GlobalVar.EnterStageIndex = tmpStateIndex; } else { GlobalVar.EnterStageIndex = 1; } AntiCheatProxy.Instance.CheckCheat(OnStartEndlessCallback); } /// /// /// private void OnStartEndlessCallback(int error, string message) { if (error == 0) { if (!TimeProxy.Instance.CostTimes(TimeProxy.武道会挑战次数)) { #if UNITY_EDITOR PostNotification(GlobalDefine.EVENT_SHOW_TOAST, "GM版本无限制进入"); #else PostNotification(GlobalDefine.EVENT_SHOW_TOAST, "武道会次数不足"); return; #endif } GameScene.Instance.EnterScene(GlobalVar.EnterLevelId); MissionProxy.Instance.OnEvent(MissionProxy.武林大会); } else { if (error == ErrorCode.TIME_CHEAT) PostNotification(GlobalDefine.EVENT_SHOW_TOAST, "请检查手机时间"); else PostNotification(GlobalDefine.EVENT_SHOW_TOAST, "武道会需要联网"); } } /// /// /// /// /// public bool CompleteEndlessLevel(int stageIndex) { if (highestEndlessStage < stageIndex) { highestEndlessStage = stageIndex; SaveLevels(); return true; } return false; } /// /// 武道会每周结算 /// public void EndlessSettle() { AntiCheatProxy.Instance.CheckCheat(this.OnEndlessSettleCallback); } /// /// /// /// private void OnEndlessSettleCallback(int error, string message) { if (error == ErrorCode.SUCCESS) { if (TimeProxy.Instance.TryTimeKey(TimeProxy.每周武道会结算)) { int result = highestEndlessStage; if (result > 0) { SendEndlessRewards(result); highestEndlessStage = result / 2; } } } } /// /// /// /// /// public Item.ItemInfo GetEndlessRewards(int stageIndex) { int high = stageIndex; if (high > 0) { var rewardIds = endlessLevel.shopBox; high -= 1; high = Mathf.Min(9, high / 10); int rewardMailId = rewardIds[high]; var mail = ItemProxy.Instance.GetStaticItem(rewardMailId); if (mail != null && mail.rewardInfos.Length > 0) { return mail.rewardInfos[0]; } } return default; } private void SendEndlessRewards(int stageIndex) { int high = stageIndex; if (high > 0) { var rewardIds = endlessLevel.shopBox; high -= 1; high = Mathf.Min(9, high / 10); int rewardMailId = rewardIds[high]; MailProxy.Instance.PostLocalMail(rewardMailId); } } #endregion /// /// /// public void StartSpecial(int levelId) { GlobalVar.EnterLevelId = levelId; GlobalVar.EnterStageIndex = 0; var levelItem = ItemProxy.Instance.GetStaticItem(currentCompletedLevel); if (levelItem != null) GlobalVar.EnterLevelFactor = levelItem.difficulty[0]; #if UNITY_EDITOR Debug.Log("开始特殊关"); #endif AntiCheatProxy.Instance.CheckCheat(OnStartSpecialCallback); } /// /// /// private void OnStartSpecialCallback(int error, string message) { if (error == ErrorCode.TIME_CHEAT) { PostNotification(GlobalDefine.EVENT_SHOW_TOAST, "请检查手机时间"); return; } GameScene.Instance.EnterScene(GlobalVar.EnterLevelId); } #region 挑战 /// /// 开始挑战 /// public void StartChallenge(int levelId) { GlobalVar.EnterLevelId = levelId; GlobalVar.EnterStageIndex = 0; #if UNITY_EDITOR Debug.Log("开始挑战"); #endif AntiCheatProxy.Instance.CheckCheat(OnStartChallengeCallback); } /// /// /// private void OnStartChallengeCallback(int error, string message) { if (error == ErrorCode.TIME_CHEAT) { PostNotification(GlobalDefine.EVENT_SHOW_TOAST, "请检查手机时间"); return; } GameScene.Instance.EnterScene(GlobalVar.EnterLevelId); } #endregion #region 剑阁 /// /// 开始爬塔 /// public void StartClimb(int stageIndex) { GlobalVar.EnterLevelId = 30000; GlobalVar.EnterStageIndex = stageIndex; #if UNITY_EDITOR Debug.Log("开始挑战"); #endif AntiCheatProxy.Instance.CheckCheat(OnStartClimbCallback); } /// /// /// private void OnStartClimbCallback(int error, string message) { if (error == ErrorCode.TIME_CHEAT) { PostNotification(GlobalDefine.EVENT_SHOW_TOAST, "请检查手机时间"); return; } GameScene.Instance.EnterScene(GlobalVar.EnterLevelId); } /// /// /// /// /// public bool CompleteClimbLevel(int stageIndex) { if (AntiCheatProxy.Instance.isCheat) { PostNotification(GlobalDefine.EVENT_SHOW_TOAST, "请不要修改时间"); return false; } SwordProxy.Instance.SetSwordLevel(stageIndex, false); return true; } #endregion private void InitLevels() { var chapters = ItemProxy.Instance.GetStaticItems(); for (int j = 0; j < chapters.Count; j++) { var chapter = chapters[j]; var levels = chapter.levels; if (levels != null && levels.Length == 2) for (int i = levels[0]; i <= levels[1]; i++) { var levelItem = ItemProxy.Instance.GetStaticItem(i); if (levelItem != null) { levelItem.chapter = chapter; if (i > _maxLevel) _maxLevel = i; } } } var endlessLevel = ItemProxy.Instance.GetStaticItem(10000); if (endlessLevel != null) { _endlessLevels.Add(new LevelInfo(endlessLevel)); } } /// /// /// private void LoadLevels() { var completedLevelId = this.currentCompletedLevel; SyncLevel(completedLevelId); _lastHighestCompletedLevel = completedLevelId; // var levelItems = ItemProxy.Instance.GetStaticItems(); for (int i = 0; i < levelItems.Count; i++) { var levelItem = levelItems[i]; if (levelItem.type == 1) { levelItem.isCompleted = levelItem.id <= completedLevelId; } else if (levelItem.type == 2) { //_endlessLevels.Add(new LevelInfo(level)); } else { } } // } /// /// /// private void SaveLevels() { } #endregion #region Proxy & Unity public static LevelProxy Instance; // Use this for initialization private void Awake() { Instance = this; } public override int priority => 20; public override void LoadCompleted() { InitLevels(); } public override void ReadArchive() { LoadLevels(); } #endregion } }