317 lines
9.5 KiB
C#
317 lines
9.5 KiB
C#
|
using System;
|
|||
|
using System.Linq;
|
|||
|
using game;
|
|||
|
using UnityEditor;
|
|||
|
using UnityEngine;
|
|||
|
using Object = UnityEngine.Object;
|
|||
|
|
|||
|
public class CheatsWindow : EditorWindow
|
|||
|
{
|
|||
|
private bool FreezeLevel
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return _freezeLevel;
|
|||
|
}
|
|||
|
set
|
|||
|
{
|
|||
|
_freezeLevel = value;
|
|||
|
G.DebugFreezeLevel = value;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private static CheatsWindow _instance = null;
|
|||
|
private static Configs _configs = null;
|
|||
|
private static GameData _save = null;
|
|||
|
private static DataGame _original = null;
|
|||
|
private static DataGame _custom = null;
|
|||
|
|
|||
|
private static bool _safeModeForSequence = false;
|
|||
|
private bool _freezeLevel;
|
|||
|
|
|||
|
public static bool IsVisible => _instance != null;
|
|||
|
|
|||
|
public static void Open()
|
|||
|
{
|
|||
|
_instance = (CheatsWindow)GetWindow(typeof(CheatsWindow));
|
|||
|
_instance.titleContent.text = "Cheats";
|
|||
|
_instance.Show();
|
|||
|
}
|
|||
|
|
|||
|
private void OnEnable()
|
|||
|
{
|
|||
|
if (_instance == null)
|
|||
|
_instance = this;
|
|||
|
Load();
|
|||
|
G.DebugFreezeLevel = _freezeLevel;
|
|||
|
}
|
|||
|
|
|||
|
public static new void Close()
|
|||
|
{
|
|||
|
((EditorWindow) _instance).Close();
|
|||
|
_instance = null;
|
|||
|
}
|
|||
|
|
|||
|
private static void Load()
|
|||
|
{
|
|||
|
_save = new GameData(Settings.VERSION);
|
|||
|
_save.UnregisterPersistentStructures();
|
|||
|
_save.TryLoadOrCreateNew();
|
|||
|
|
|||
|
_original = _save.DevGetState();
|
|||
|
_custom = (DataGame)_original.clone();
|
|||
|
|
|||
|
LoadConfigs();
|
|||
|
LoadGameSettings();
|
|||
|
}
|
|||
|
|
|||
|
private static void LoadConfigs()
|
|||
|
{
|
|||
|
var asset = Resources.Load<TextAsset>("ext_config/configs/packed_bundle");
|
|||
|
(_configs = new Configs()).Load(new System.IO.MemoryStream(asset.bytes));
|
|||
|
}
|
|||
|
|
|||
|
private static void LoadGameSettings()
|
|||
|
{
|
|||
|
var levels = _configs.Get<ConfGameLevels>("@game_levels");
|
|||
|
var buffs = _configs.Get<ConfGameBuffs>("@game_buffs");
|
|||
|
GameSettings.Load(levels, buffs);
|
|||
|
}
|
|||
|
|
|||
|
private void OnGUI()
|
|||
|
{
|
|||
|
Render();
|
|||
|
}
|
|||
|
|
|||
|
private void Render()
|
|||
|
{
|
|||
|
EditorGUILayout.BeginHorizontal();
|
|||
|
TabOfCurrentData();
|
|||
|
TabOfSettings();
|
|||
|
EditorGUILayout.EndHorizontal();
|
|||
|
|
|||
|
Sequence();
|
|||
|
Buttons();
|
|||
|
TabOfHotkeys();
|
|||
|
}
|
|||
|
|
|||
|
private static void TabOfCurrentData()
|
|||
|
{
|
|||
|
EditorGUILayout.BeginVertical(GUI.skin.box);
|
|||
|
Title("Original");
|
|||
|
GUILayout.Label($"Completed: {_original.progress.completed}");
|
|||
|
int coinsItem = _original.inventory.purchased.FindIndex(i => i.protoId == EnumConsumable.COIN.GetItemID());
|
|||
|
uint coinsAmount = _original.inventory.purchased.HasIndex(coinsItem)
|
|||
|
? _original.inventory.purchased[coinsItem].amount
|
|||
|
: 0;
|
|||
|
GUILayout.Label($"Coins: {coinsAmount}");
|
|||
|
EditorGUILayout.EndVertical();
|
|||
|
}
|
|||
|
|
|||
|
private static void Title(string text)
|
|||
|
{
|
|||
|
GUILayout.Label(text, new GUIStyle(EditorStyles.label)
|
|||
|
{
|
|||
|
alignment = TextAnchor.MiddleCenter,
|
|||
|
margin = new RectOffset(0, 0, 12, 6),
|
|||
|
fontSize = 16
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
private void TabOfSettings()
|
|||
|
{
|
|||
|
EditorGUILayout.BeginVertical(GUI.skin.box);
|
|||
|
Title("Custom");
|
|||
|
|
|||
|
EditorGUILayout.BeginHorizontal();
|
|||
|
CompletedInput();
|
|||
|
EditorGUILayout.EndHorizontal();
|
|||
|
|
|||
|
EditorGUILayout.BeginHorizontal();
|
|||
|
GUILayout.Label("Coins:", GUILayout.ExpandWidth(false));
|
|||
|
int coinsItemIndex = _custom.inventory.purchased.FindIndex(c =>
|
|||
|
c.protoId == EnumConsumable.COIN.GetItemID());
|
|||
|
|
|||
|
if (_custom.inventory.purchased.HasIndex(coinsItemIndex) == false)
|
|||
|
{
|
|||
|
_custom.inventory.purchased.Add(new DataItem
|
|||
|
{ amount = 0, protoId = EnumConsumable.COIN.GetItemID()});
|
|||
|
coinsItemIndex = _custom.inventory.purchased.FindIndex(c =>
|
|||
|
c.protoId == EnumConsumable.COIN.GetItemID());
|
|||
|
}
|
|||
|
|
|||
|
DataItem coinsItem = _custom.inventory.purchased[coinsItemIndex];
|
|||
|
coinsItem.amount = (uint)EditorGUILayout.IntField((int)coinsItem.amount);
|
|||
|
_custom.inventory.purchased[coinsItemIndex] = coinsItem;
|
|||
|
|
|||
|
EditorGUILayout.EndHorizontal();
|
|||
|
|
|||
|
EditorGUILayout.BeginHorizontal();
|
|||
|
GUILayout.Label($"Safe Mode:", GUILayout.ExpandWidth(false));
|
|||
|
_safeModeForSequence = GUILayout.Toggle(_safeModeForSequence, "");
|
|||
|
GUILayout.Label($"Freeze level:", GUILayout.ExpandWidth(false));
|
|||
|
FreezeLevel = GUILayout.Toggle(FreezeLevel, "");
|
|||
|
EditorGUILayout.EndHorizontal();
|
|||
|
EditorGUILayout.EndVertical();
|
|||
|
}
|
|||
|
|
|||
|
private static void CompletedInput()
|
|||
|
{
|
|||
|
GUILayout.Label("Completed: ", GUILayout.ExpandWidth(false));
|
|||
|
var completedInput = (uint)EditorGUILayout.IntField((int)_custom.progress.completed);
|
|||
|
|
|||
|
if (completedInput == _custom.progress.completed)
|
|||
|
return;
|
|||
|
|
|||
|
if (_safeModeForSequence)
|
|||
|
{
|
|||
|
_custom.progress.completed =
|
|||
|
(uint)Mathf.Min(completedInput, _custom.progress.sequence.Count - 1);
|
|||
|
GUI.FocusControl(null);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
_custom.progress.completed = completedInput;
|
|||
|
}
|
|||
|
|
|||
|
var defaultSequenceLenght = GameSettings.Levels.DefaultSequence.Count + GameSettings.Levels.TutorialLenght;
|
|||
|
var sequenceMustBeDefault = completedInput < defaultSequenceLenght;
|
|||
|
|
|||
|
if (sequenceMustBeDefault)
|
|||
|
{
|
|||
|
_custom.progress.sequence = SequenceBuilder.BuildDefaultWithTutorial();
|
|||
|
_custom.progress.position = completedInput;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
var outOfSequence = completedInput > _custom.progress.sequence.Count;
|
|||
|
|
|||
|
if (outOfSequence)
|
|||
|
{
|
|||
|
_custom.progress.position = 0;
|
|||
|
_custom.progress.sequence = SequenceBuilder.BuildByPattern(GameSettings.Levels.GetRandomPattern());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
_custom.progress.position = completedInput;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void Sequence()
|
|||
|
{
|
|||
|
EditorGUILayout.BeginVertical(GUI.skin.box);
|
|||
|
Title("Sequence");
|
|||
|
EditorGUILayout.BeginHorizontal();
|
|||
|
|
|||
|
if (_custom.progress.sequence.IsEmpty())
|
|||
|
_custom.progress.sequence = SequenceBuilder.BuildDefaultWithTutorial();
|
|||
|
|
|||
|
var sequence = _custom.progress.sequence;
|
|||
|
var buttonsStyle = GetLevelButtonStyle();
|
|||
|
var bonusLevels = GameSettings.Levels.GetIDsBy(l => l.Type == EnumLevelType.TUTORIAL);
|
|||
|
var bossLevels = GameSettings.Levels.GetIDsBy(l => l.Type == EnumLevelType.BOSS);
|
|||
|
const int itemsPerLine = 10;
|
|||
|
|
|||
|
for (int i = 0; i < sequence.Count; i++)
|
|||
|
{
|
|||
|
if (_custom.progress.position == i)
|
|||
|
{
|
|||
|
buttonsStyle.normal.background = CreateTexture(Color.red);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (bonusLevels.Contains(sequence[i]))
|
|||
|
buttonsStyle.normal.background = CreateTexture(new Color(0, 0.2f, 0));
|
|||
|
else if (bossLevels.Contains(sequence[i]))
|
|||
|
buttonsStyle.normal.background = CreateTexture(new Color(0.2f, 0.2f, 0));
|
|||
|
else
|
|||
|
buttonsStyle.normal.background = CreateTexture(Color.black);
|
|||
|
}
|
|||
|
|
|||
|
if (GUILayout.Button($"{sequence[i]}", buttonsStyle))
|
|||
|
{
|
|||
|
_custom.progress.position = (uint) i;
|
|||
|
_custom.progress.completed = (uint) Mathf.Max(0, i - _original.progress.completed);
|
|||
|
}
|
|||
|
|
|||
|
if ((i + 1) % itemsPerLine == 0)
|
|||
|
{
|
|||
|
EditorGUILayout.EndHorizontal();
|
|||
|
EditorGUILayout.BeginHorizontal();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
EditorGUILayout.EndHorizontal();
|
|||
|
EditorGUILayout.EndVertical();
|
|||
|
}
|
|||
|
|
|||
|
private static GUIStyle GetLevelButtonStyle()
|
|||
|
{
|
|||
|
var button = new GUIStyle(EditorStyles.label)
|
|||
|
{
|
|||
|
alignment = TextAnchor.MiddleCenter,
|
|||
|
margin = new RectOffset(0, 0, 12, 6),
|
|||
|
fontSize = 12,
|
|||
|
normal = {textColor = Color.white}
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
return button;
|
|||
|
}
|
|||
|
|
|||
|
private static Texture2D CreateTexture(Color color)
|
|||
|
{
|
|||
|
var texture = new Texture2D(1, 1);
|
|||
|
texture.SetPixel(1, 1, color);
|
|||
|
texture.Apply();
|
|||
|
|
|||
|
return texture;
|
|||
|
}
|
|||
|
|
|||
|
private static void Buttons()
|
|||
|
{
|
|||
|
EditorGUILayout.BeginHorizontal();
|
|||
|
|
|||
|
if (GUILayout.Button("Open"))
|
|||
|
OpenPrefab();
|
|||
|
|
|||
|
if (GUILayout.Button("Save"))
|
|||
|
Save();
|
|||
|
|
|||
|
if (GUILayout.Button("Reset"))
|
|||
|
{
|
|||
|
GameData.ClearAll();
|
|||
|
Load();
|
|||
|
}
|
|||
|
|
|||
|
EditorGUILayout.EndHorizontal();
|
|||
|
}
|
|||
|
|
|||
|
private static void OpenPrefab()
|
|||
|
{
|
|||
|
string levelName = LevelSettings.GetPrefabPath(_custom.progress.sequence[(int)_custom.progress.completed]);
|
|||
|
AssetDatabase.OpenAsset(AssetDatabase.LoadAssetAtPath<Object>($"Assets/Resources/{levelName}.prefab"));
|
|||
|
}
|
|||
|
|
|||
|
private static void Save()
|
|||
|
{
|
|||
|
Error.Assert(EditorApplication.isPlaying == false, "Removed state files might be rewritten by running game");
|
|||
|
PersistError error = _save.DevWriteToFile(GameData.DefaultDataFile, _custom);
|
|||
|
Log.Debug($"CheatsWindow.Save: {error.Code}");
|
|||
|
|
|||
|
_save.TryLoadOrCreateNew();
|
|||
|
_original = _save.DevGetState();
|
|||
|
_custom = (DataGame)_original.clone();
|
|||
|
}
|
|||
|
|
|||
|
private static void TabOfHotkeys()
|
|||
|
{
|
|||
|
EditorGUILayout.BeginHorizontal();
|
|||
|
EditorGUILayout.HelpBox(
|
|||
|
"Toggle UI visibility: (SPACE)\n" +
|
|||
|
"", MessageType.Info);
|
|||
|
EditorGUILayout.EndHorizontal();
|
|||
|
}
|
|||
|
}
|