2025-05-18 01:04:31 +08:00

1036 lines
32 KiB
C#

// ***********************************************************************
// Assembly : Game
// Author : Kimch
// Created : 2020-12-08
// Description :
// Last Modified By :
// Last Modified On :
// ***********************************************************************
// <copyright file= "LevelProxy" company="Kunpo"></copyright>
// <summary></summary>
// ***********************************************************************
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace G
{
/// <summary>
///
/// </summary>
public class LevelProxy : F.GameProxy
{
/// <summary>
/// 关卡信息
/// </summary>
public struct LevelInfo
{
public readonly ItemLevel item;
/// <summary>
///
/// </summary>
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<LevelInfo> _normalLevels = new List<LevelInfo>();
private readonly List<LevelInfo> _endlessLevels = new List<LevelInfo>();
private readonly List<LevelInfo> _climbLevels = new List<LevelInfo>();
#endregion
#region Property
/// <summary>
///
/// </summary>
public int maxLevelId
{
get { return _maxLevel; }
}
/// <summary>
///
/// </summary>
public int maxChapterId
{
get { return 0; }
}
/// <summary>
/// 当前章节
/// </summary>
public int currentChapterId
{
get;
private set;
}
/// <summary>
///
/// </summary>
public ItemChapter currentChapterItem
{
get
{
var result = ItemProxy.Instance.GetStaticItem<ItemChapter>(currentChapterId);
return result ?? ItemProxy.Instance.GetStaticItem<ItemChapter>(1);
}
}
/// <summary>
/// 最大关
/// </summary>
public int currentUnlockedLevel
{
get;
private set;
}
/// <summary>
/// 最大关(完成)
/// </summary>
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<ItemLevel>(currentCompletedLevel);
}
}
/// <summary>
/// 新通关关卡
/// </summary>
public int newCompletedLevel
{
get
{
int completedLevel = this.currentCompletedLevel;
var result = completedLevel != _lastHighestCompletedLevel;
if (result)
_lastHighestCompletedLevel = completedLevel;
return result ? _lastHighestCompletedLevel : 0;
}
}
/// <summary>
/// 最大无尽关卡 每周清版
/// </summary>
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);
}
}
/// <summary>
///
/// </summary>
public Item.ItemInfo highestEndlessRewards
{
get
{
return GetEndlessRewards(highestEndlessStage);
}
}
/// <summary>
///
/// </summary>
public ItemLevel endlessLevel
{
get
{
if (_endlessLevels.Count > 0)
return _endlessLevels[0].item;
return ItemProxy.Instance.GetStaticItem<ItemLevel>(10000);
}
}
/// <summary>
///
/// </summary>
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
/// <summary>
///
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
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;
}
/// <summary>
///
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
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;
}
/// <summary>
///
/// </summary>
/// <param name="value"></param>
private void SyncLevel(int value)
{
this.currentUnlockedLevel = Mathf.Clamp(value + 1, 1, _maxLevel);
var unlockLevelItem = ItemProxy.Instance.GetStaticItem<ItemLevel>(currentUnlockedLevel);
if (unlockLevelItem != null)
{
this.currentChapterId = unlockLevelItem.chapterId;
}
}
/// <summary>
/// 完成关卡
/// </summary>
/// <param name="levelId"></param>
public bool CompleteLevel(int levelId, int stageIndex)
{
var levelItem = ItemProxy.Instance.GetStaticItem<ItemLevel>(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;
}
/// <summary>
///
/// </summary>
/// <param name="levelId"></param>
/// <param name="stateIndex"></param>
public void RestartLevel()
{
GlobalVar.EnterLevelFactor = 0;
GameScene.Instance.EnterScene(GlobalVar.EnterLevelId);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
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;
}
/// <summary>
///
/// </summary>
/// <param name="levelId"></param>
/// <param name="stageIndex"></param>
/// <param name="data"></param>
public void SavePlayingLevelState(int levelId, int stageIndex, List<int> 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();
}
}
}
/// <summary>
///
/// </summary>
public void RemovePlayingLevelState()
{
GlobalVar.EnterLevelId = 0;
GlobalVar.EnterStageIndex = 0;
GlobalVar.SavePlayingStateData.Clear();
CodeStage.AntiCheat.Storage.ObscuredPrefs.DeleteKey("bt_state");
CodeStage.AntiCheat.Storage.ObscuredPrefs.Save();
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public int AgainStartLevel()
{
return StartLevel(GlobalVar.EnterLevelId);
}
/// <summary>
///
/// </summary>
public void FirstLevel()
{
GlobalVar.EnterLevelId = 1;
GlobalVar.EnterStageIndex = 0;
GlobalVar.EnterLevelFactor = 0;
GameScene.Instance.EnterScene(GlobalVar.EnterLevelId);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
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);
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
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;
}
/// <summary>
///
/// </summary>
/// <param name="error"></param>
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);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
private int CheckStartLevel()
{
if (!PlayerProxy.Instance.CheckEnergyForLevel())
{
return 2;
}
if (BagProxy.Instance.BagIsFull())
{
return 1;
}
return 0;
}
/// <summary>
/// 扫荡
/// </summary>
/// <param name="levelId"></param>
/// <returns></returns>
public int SweepLevel(int levelId)
{
int result = CheckStartLevel();
if (result == 0)
{
GlobalVar.EnterLevelId = levelId;
GlobalVar.EnterStageIndex = 0;
AntiCheatProxy.Instance.CheckCheat(OnSweepLevelCallback);
}
return result;
}
/// <summary>
/// 扫荡
/// </summary>
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();
}
});
}
/// <summary>
///
/// </summary>
private void SweepLevelSettle()
{
PlayerProxy.Instance.UseEnergyForLevel();
TimeProxy.Instance.CostTimes(TimeProxy.);
var battleResult = GetSweepResult(GlobalVar.EnterLevelId);
KUIWindow.OpenWindow<UI.SettleWindow>(battleResult);
}
/// <summary>
///
/// </summary>
/// <param name="levelId"></param>
/// <returns></returns>
private BattleResult GetSweepResult(int levelId, bool offline = false)
{
var curLevelItem = ItemProxy.Instance.GetStaticItem<ItemLevel>(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<ItemStage>(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<ItemStage>(stageId);
stageId = GlobalUtils.GetRandom(lastStage.nextStages);
if (stageId <= 0)
{
stageId = lastStage.id;
}
}
curStageIndex = maxStageIndex;
}
var currStage = ItemProxy.Instance.GetStaticItem<ItemStage>(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<Item.ItemInfo>.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<ItemProp>(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<Item.ItemInfo>.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;
}
/// <summary>
///
/// </summary>
/// <param name="overflow"></param>
/// <param name="callback"></param>
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<UI.OfflineWindow>(battleResult);
}
#region
/// <summary>
/// 开始武道会
/// </summary>
/// <param name="restart"></param>
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);
}
/// <summary>
///
/// </summary>
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, "武道会需要联网");
}
}
/// <summary>
///
/// </summary>
/// <param name="stageIndex"></param>
/// <returns></returns>
public bool CompleteEndlessLevel(int stageIndex)
{
if (highestEndlessStage < stageIndex)
{
highestEndlessStage = stageIndex;
SaveLevels();
return true;
}
return false;
}
/// <summary>
/// 武道会每周结算
/// </summary>
public void EndlessSettle()
{
AntiCheatProxy.Instance.CheckCheat(this.OnEndlessSettleCallback);
}
/// <summary>
///
/// </summary>
/// <param name="error"></param>
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;
}
}
}
}
/// <summary>
///
/// </summary>
/// <param name="stageIndex"></param>
/// <returns></returns>
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<ItemMail>(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
/// <summary>
///
/// </summary>
public void StartSpecial(int levelId)
{
GlobalVar.EnterLevelId = levelId;
GlobalVar.EnterStageIndex = 0;
var levelItem = ItemProxy.Instance.GetStaticItem<ItemLevel>(currentCompletedLevel);
if (levelItem != null)
GlobalVar.EnterLevelFactor = levelItem.difficulty[0];
#if UNITY_EDITOR
Debug.Log("开始特殊关");
#endif
AntiCheatProxy.Instance.CheckCheat(OnStartSpecialCallback);
}
/// <summary>
///
/// </summary>
private void OnStartSpecialCallback(int error, string message)
{
if (error == ErrorCode.TIME_CHEAT)
{
PostNotification(GlobalDefine.EVENT_SHOW_TOAST, "请检查手机时间");
return;
}
GameScene.Instance.EnterScene(GlobalVar.EnterLevelId);
}
#region
/// <summary>
/// 开始挑战
/// </summary>
public void StartChallenge(int levelId)
{
GlobalVar.EnterLevelId = levelId;
GlobalVar.EnterStageIndex = 0;
#if UNITY_EDITOR
Debug.Log("开始挑战");
#endif
AntiCheatProxy.Instance.CheckCheat(OnStartChallengeCallback);
}
/// <summary>
///
/// </summary>
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
/// <summary>
/// 开始爬塔
/// </summary>
public void StartClimb(int stageIndex)
{
GlobalVar.EnterLevelId = 30000;
GlobalVar.EnterStageIndex = stageIndex;
#if UNITY_EDITOR
Debug.Log("开始挑战");
#endif
AntiCheatProxy.Instance.CheckCheat(OnStartClimbCallback);
}
/// <summary>
///
/// </summary>
private void OnStartClimbCallback(int error, string message)
{
if (error == ErrorCode.TIME_CHEAT)
{
PostNotification(GlobalDefine.EVENT_SHOW_TOAST, "请检查手机时间");
return;
}
GameScene.Instance.EnterScene(GlobalVar.EnterLevelId);
}
/// <summary>
///
/// </summary>
/// <param name="stageIndex"></param>
/// <returns></returns>
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<ItemChapter>();
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<ItemLevel>(i);
if (levelItem != null)
{
levelItem.chapter = chapter;
if (i > _maxLevel)
_maxLevel = i;
}
}
}
var endlessLevel = ItemProxy.Instance.GetStaticItem<ItemLevel>(10000);
if (endlessLevel != null)
{
_endlessLevels.Add(new LevelInfo(endlessLevel));
}
}
/// <summary>
///
/// </summary>
private void LoadLevels()
{
var completedLevelId = this.currentCompletedLevel;
SyncLevel(completedLevelId);
_lastHighestCompletedLevel = completedLevelId;
//
var levelItems = ItemProxy.Instance.GetStaticItems<ItemLevel>();
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
{
}
}
//
}
/// <summary>
///
/// </summary>
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
}
}