Added setup for DunGen generation dev tools
This commit is contained in:
parent
e2aba5fcdb
commit
3160685123
|
@ -1,10 +1,13 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection.Emit;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DunGen;
|
using DunGen;
|
||||||
using DunGen.Graph;
|
using DunGen.Graph;
|
||||||
|
using DunGenPlus.Generation;
|
||||||
|
using LethalLevelLoader;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace DunGenPlus
|
namespace DunGenPlus
|
||||||
|
@ -68,6 +71,31 @@ namespace DunGenPlus
|
||||||
return Plugin.DunGenExtenders.ContainsKey(dungeonFlow);
|
return Plugin.DunGenExtenders.ContainsKey(dungeonFlow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if <paramref name="extendedDungeonFlow"/> has a registered <see cref="DunGenExtender"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="extendedDungeonFlow"></param>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true"/> if <paramref name="extendedDungeonFlow"/> has a registered <see cref="DunGenExtender"/>.
|
||||||
|
/// <see langword="false"/> otherwise.
|
||||||
|
/// </returns>
|
||||||
|
public static bool ContainsDungeonFlow(ExtendedDungeonFlow extendedDungeonFlow) {
|
||||||
|
if (extendedDungeonFlow == null) return false;
|
||||||
|
return ContainsDungeonFlow(extendedDungeonFlow.DungeonFlow);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns corresponding <see cref="DunGenExtender"/> for <paramref name="dungeonFlow"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dungeonFlow"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static DunGenExtender GetDunGenExtender(DungeonFlow dungeonFlow) {
|
||||||
|
if (Plugin.DunGenExtenders.TryGetValue(dungeonFlow, out var value)) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates and returns an empty <see cref="DunGenExtender"/>.
|
/// Creates and returns an empty <see cref="DunGenExtender"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -8,8 +8,13 @@ using System.Threading.Tasks;
|
||||||
using BepInEx;
|
using BepInEx;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using LethalLevelLoader;
|
using LethalLevelLoader;
|
||||||
|
using DunGen.Graph;
|
||||||
|
using DunGen;
|
||||||
|
using System.Reflection;
|
||||||
|
using Unity.Netcode;
|
||||||
|
|
||||||
namespace DunGenPlus {
|
namespace DunGenPlus {
|
||||||
|
|
||||||
internal class Assets {
|
internal class Assets {
|
||||||
|
|
||||||
public static void LoadAssets() {
|
public static void LoadAssets() {
|
||||||
|
@ -34,5 +39,44 @@ namespace DunGenPlus {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static AssetBundle MainAssetBundle = null;
|
||||||
|
public static GameObject DevDebugPrefab;
|
||||||
|
|
||||||
|
public static T Load<T>(string name, bool onlyReportErrors = true) where T : UnityEngine.Object {
|
||||||
|
if (MainAssetBundle == null) {
|
||||||
|
Plugin.logger.LogError($"Trying to load in asset but asset bundle is missing");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var asset = MainAssetBundle.LoadAsset<T>(name);
|
||||||
|
var missingasset = asset == null;
|
||||||
|
|
||||||
|
if (missingasset || onlyReportErrors == true) {
|
||||||
|
Plugin.logger.LogDebug($"Loading asset {name}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (missingasset) {
|
||||||
|
Plugin.logger.LogError($"...but it was not found");
|
||||||
|
}
|
||||||
|
return asset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void LoadAssetBundle() {
|
||||||
|
if (MainAssetBundle == null) {
|
||||||
|
var assembly = Assembly.GetExecutingAssembly();
|
||||||
|
var resourceNames = assembly.GetManifestResourceNames();
|
||||||
|
if (resourceNames.Length >= 1) {
|
||||||
|
var name = resourceNames[0];
|
||||||
|
using (var assetStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name)) {
|
||||||
|
Plugin.logger.LogDebug($"Loading resource {name}");
|
||||||
|
MainAssetBundle = AssetBundle.LoadFromStream(assetStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DevDebugPrefab = Load<GameObject>("DevDebug");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,45 +125,46 @@ namespace DunGenPlus.Collections {
|
||||||
|
|
||||||
internal Bounds GetDungeonBounds(float dungeonScale) {
|
internal Bounds GetDungeonBounds(float dungeonScale) {
|
||||||
var size = DungeonSizeBase + Vector3.Scale(DungeonSizeBase * (dungeonScale - 1), DungeonSizeFactor);
|
var size = DungeonSizeBase + Vector3.Scale(DungeonSizeBase * (dungeonScale - 1), DungeonSizeFactor);
|
||||||
var offset = DungeonPositionOffset + Vector3.Scale(size, DungeonPositionPivot);
|
var offset = DungeonPositionOffset + Vector3.Scale(size, DungeonPositionPivot - Vector3.one * 0.5f);
|
||||||
return new Bounds(offset, size);
|
return new Bounds(offset, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void CopyFrom(DunGenExtenderProperties props) {
|
||||||
|
MainPathCount = props.MainPathCount;
|
||||||
|
MainRoomTilePrefab = props.MainRoomTilePrefab;
|
||||||
|
MainPathCopyNodeBehaviour = props.MainPathCopyNodeBehaviour;
|
||||||
|
|
||||||
|
UseDungeonBounds = props.UseDungeonBounds;
|
||||||
|
DungeonSizeBase = props.DungeonSizeBase;
|
||||||
|
DungeonSizeFactor = props.DungeonSizeFactor;
|
||||||
|
DungeonPositionOffset = props.DungeonPositionOffset;
|
||||||
|
DungeonPositionPivot = props.DungeonPositionPivot;
|
||||||
|
|
||||||
|
AddArchetypesToNormalNodes = props.AddArchetypesToNormalNodes;
|
||||||
|
NormalNodeArchetypes = props.NormalNodeArchetypes;
|
||||||
|
|
||||||
|
UseForcedTiles = props.UseForcedTiles;
|
||||||
|
ForcedTileSets = props.ForcedTileSets;
|
||||||
|
|
||||||
|
UseBranchLoopBoost = props.UseBranchLoopBoost;
|
||||||
|
BranchLoopBoostTileSearch = props.BranchLoopBoostTileSearch;
|
||||||
|
BranchLoopBoostTileScale = props.BranchLoopBoostTileScale;
|
||||||
|
|
||||||
|
UseLineRandomizer = props.UseLineRandomizer;
|
||||||
|
LineRandomizerTileSets = props.LineRandomizerTileSets;
|
||||||
|
LineRandomizerArchetypes = props.LineRandomizerArchetypes;
|
||||||
|
LineRandomizerTakeCount = props.LineRandomizerTakeCount;
|
||||||
|
|
||||||
|
UseMaxShadowsRequestUpdate = props.UseMaxShadowsRequestUpdate;
|
||||||
|
MaxShadowsRequestAmount = props.MaxShadowsRequestAmount;
|
||||||
|
|
||||||
|
UseDoorwaySisters = props.UseDoorwaySisters;
|
||||||
|
UseRandomGuaranteedScrapSpawn = props.UseRandomGuaranteedScrapSpawn;
|
||||||
|
}
|
||||||
|
|
||||||
internal DunGenExtenderProperties Copy() {
|
internal DunGenExtenderProperties Copy() {
|
||||||
var copy = new DunGenExtenderProperties();
|
var copy = new DunGenExtenderProperties();
|
||||||
|
copy.CopyFrom(this);
|
||||||
copy.MainPathCount = MainPathCount;
|
|
||||||
copy.MainRoomTilePrefab = MainRoomTilePrefab;
|
|
||||||
copy.MainPathCopyNodeBehaviour = MainPathCopyNodeBehaviour;
|
|
||||||
//copy.MainPathCopyInjectionTiles = MainPathCopyInjectionTiles;
|
|
||||||
|
|
||||||
copy.UseDungeonBounds = UseDungeonBounds;
|
|
||||||
copy.DungeonSizeBase = DungeonSizeBase;
|
|
||||||
copy.DungeonSizeFactor = DungeonSizeFactor;
|
|
||||||
copy.DungeonPositionOffset = DungeonPositionOffset;
|
|
||||||
copy.DungeonPositionPivot = DungeonPositionPivot;
|
|
||||||
|
|
||||||
copy.AddArchetypesToNormalNodes = AddArchetypesToNormalNodes;
|
|
||||||
copy.NormalNodeArchetypes = NormalNodeArchetypes;
|
|
||||||
|
|
||||||
copy.UseForcedTiles = UseForcedTiles;
|
|
||||||
copy.ForcedTileSets = ForcedTileSets;
|
|
||||||
|
|
||||||
copy.UseBranchLoopBoost = UseBranchLoopBoost;
|
|
||||||
copy.BranchLoopBoostTileSearch = BranchLoopBoostTileSearch;
|
|
||||||
copy.BranchLoopBoostTileScale = BranchLoopBoostTileScale;
|
|
||||||
|
|
||||||
copy.UseLineRandomizer = UseLineRandomizer;
|
|
||||||
copy.LineRandomizerTileSets = LineRandomizerTileSets;
|
|
||||||
copy.LineRandomizerArchetypes = LineRandomizerArchetypes;
|
|
||||||
copy.LineRandomizerTakeCount = LineRandomizerTakeCount;
|
|
||||||
|
|
||||||
copy.UseMaxShadowsRequestUpdate = UseMaxShadowsRequestUpdate;
|
|
||||||
copy.MaxShadowsRequestAmount = MaxShadowsRequestAmount;
|
|
||||||
|
|
||||||
copy.UseDoorwaySisters = UseDoorwaySisters;
|
|
||||||
copy.UseRandomGuaranteedScrapSpawn = UseRandomGuaranteedScrapSpawn;
|
|
||||||
|
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DunGenPlus.Collections {
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/4632945/why-doesnt-dictionarytkey-tvalue-support-null-key
|
||||||
|
internal struct NullObject<T> where T: class{
|
||||||
|
public T Item;
|
||||||
|
private bool isNull;
|
||||||
|
|
||||||
|
public NullObject(T item, bool isNull) {
|
||||||
|
this.Item = item;
|
||||||
|
this.isNull = isNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public NullObject(T item) : this(item, item == null){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static implicit operator T(NullObject<T> nullObject) {
|
||||||
|
return nullObject.Item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator NullObject<T>(T item) {
|
||||||
|
return new NullObject<T>(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString() {
|
||||||
|
return (Item != null) ? Item.ToString() : "NULL";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj) {
|
||||||
|
if (obj == null) return isNull;
|
||||||
|
if (!(obj is NullObject<T>)) return false;
|
||||||
|
var no = (NullObject<T>)obj;
|
||||||
|
if (isNull) return no.isNull;
|
||||||
|
if (no.isNull) return false;
|
||||||
|
return Item.Equals(no.Item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode(){
|
||||||
|
if (isNull) return 0;
|
||||||
|
var result = Item.GetHashCode();
|
||||||
|
if (result >= 0) result++;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,201 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
using DunGen;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using TMPro;
|
||||||
|
using DunGen.Graph;
|
||||||
|
using LethalLevelLoader;
|
||||||
|
using UnityEngine.InputSystem;
|
||||||
|
using DunGenPlus.DevTools.Panels;
|
||||||
|
using DunGenPlus.DevTools.UIElements;
|
||||||
|
|
||||||
|
namespace DunGenPlus.DevTools {
|
||||||
|
internal partial class DevDebugManager : MonoBehaviour {
|
||||||
|
public static DevDebugManager Instance { get; private set; }
|
||||||
|
|
||||||
|
[Header("References")]
|
||||||
|
public RuntimeDungeon dungeon;
|
||||||
|
public GameObject devCamera;
|
||||||
|
public BasePanel[] panels;
|
||||||
|
|
||||||
|
public TMP_Dropdown dungeonFlowSelectionDropDown;
|
||||||
|
private ExtendedDungeonFlow[] dungeonFlows;
|
||||||
|
internal ExtendedDungeonFlow selectedDungeonFlow;
|
||||||
|
|
||||||
|
public TextMeshProUGUI statusTextMesh;
|
||||||
|
public TextMeshProUGUI statsTextMesh;
|
||||||
|
|
||||||
|
// fake
|
||||||
|
private GameObject disabledGameObject;
|
||||||
|
private RoundManager fakeRoundManager;
|
||||||
|
|
||||||
|
// cache
|
||||||
|
private Camera lastMainCamera;
|
||||||
|
private Vector3 lastCameraPosition;
|
||||||
|
private Quaternion lastCameraRotation;
|
||||||
|
|
||||||
|
void Awake(){
|
||||||
|
Instance = this;
|
||||||
|
|
||||||
|
Cursor.lockState = CursorLockMode.None;
|
||||||
|
Cursor.visible = true;
|
||||||
|
|
||||||
|
CacheMainCamera();
|
||||||
|
BeginDevCamera();
|
||||||
|
GetAllDungeonFlows();
|
||||||
|
|
||||||
|
foreach(var p in panels) p.AwakeCall();
|
||||||
|
OpenPanel(0);
|
||||||
|
|
||||||
|
dungeon.Generator.OnGenerationStatusChanged += OnDungeonFinished;
|
||||||
|
|
||||||
|
disabledGameObject = new GameObject("Disabled GOBJ");
|
||||||
|
disabledGameObject.SetActive(false);
|
||||||
|
disabledGameObject.transform.SetParent(transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDestroy(){
|
||||||
|
Instance = null;
|
||||||
|
|
||||||
|
EndDevCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(){
|
||||||
|
statusTextMesh.text = dungeon.Generator.Status.ToString();
|
||||||
|
|
||||||
|
if (!DevDebugOpen.IsSinglePlayerInShip()) {
|
||||||
|
CloseDevDebug();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Mouse.current.middleButton.isPressed) {
|
||||||
|
var delta = Mouse.current.delta.value;
|
||||||
|
var movement = delta;
|
||||||
|
devCamera.transform.position += new Vector3(-movement.x, 0f, -movement.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OpenPanel(int index) {
|
||||||
|
for(var i = 0; i < panels.Length; ++i) {
|
||||||
|
panels[i].SetPanelVisibility(i == index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectDungeonFlow(int index){
|
||||||
|
selectedDungeonFlow = dungeonFlows[index];
|
||||||
|
dungeon.Generator.DungeonFlow = selectedDungeonFlow.DungeonFlow;
|
||||||
|
UpdatePlusPanel();
|
||||||
|
Plugin.logger.LogInfo($"Selecting {selectedDungeonFlow.DungeonName}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GenerateDungeon(){
|
||||||
|
DeleteDungeon();
|
||||||
|
Plugin.logger.LogInfo($"Generating dungeon: {dungeon.Generator.IsGenerating}");
|
||||||
|
|
||||||
|
fakeRoundManager = disabledGameObject.AddComponent<RoundManager>();
|
||||||
|
fakeRoundManager.dungeonGenerator = dungeon;
|
||||||
|
|
||||||
|
selectedDungeonFlow.DungeonEvents.onBeforeDungeonGenerate?.Invoke(fakeRoundManager);
|
||||||
|
DungeonManager.GlobalDungeonEvents?.onBeforeDungeonGenerate?.Invoke(fakeRoundManager);
|
||||||
|
|
||||||
|
dungeon.Generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteDungeon(){
|
||||||
|
Plugin.logger.LogInfo($"Deleting dungeon");
|
||||||
|
dungeon.Generator.Clear(true);
|
||||||
|
dungeon.Generator.Cancel();
|
||||||
|
|
||||||
|
dungeon.Generator.RestrictDungeonToBounds = false;
|
||||||
|
|
||||||
|
if (fakeRoundManager) Destroy(fakeRoundManager);
|
||||||
|
|
||||||
|
ClearTransformChildren(dungeon.Root.transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearTransformChildren(Transform root){
|
||||||
|
var childCount = root.childCount;
|
||||||
|
for(var i = childCount - 1; i >= 0; --i) {
|
||||||
|
GameObject.Destroy(root.GetChild(i).gameObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CloseDevDebug(){
|
||||||
|
DeleteDungeon();
|
||||||
|
Destroy(gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnDungeonFinished(DungeonGenerator generator, GenerationStatus status) {
|
||||||
|
var textList = new List<string>();
|
||||||
|
if (status == GenerationStatus.Complete) {
|
||||||
|
textList.Add($"Tiles: {generator.CurrentDungeon.AllTiles.Count}");
|
||||||
|
textList.Add($"Main Tiles: {generator.CurrentDungeon.MainPathTiles.Count}");
|
||||||
|
textList.Add($"Branch Tiles: {generator.CurrentDungeon.BranchPathTiles.Count}");
|
||||||
|
textList.Add($"Doors: {generator.CurrentDungeon.Doors.Count}");
|
||||||
|
} else if (status == GenerationStatus.Failed) {
|
||||||
|
textList.Add("<color=red>Failed</color>");
|
||||||
|
}
|
||||||
|
|
||||||
|
textList.Add("<u>DunGen</u>");
|
||||||
|
textList.Add(generator.GenerationStats.ToString());
|
||||||
|
|
||||||
|
SetNewSeed();
|
||||||
|
statsTextMesh.text = string.Join("\n", textList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetNewSeed(){
|
||||||
|
foreach(var p in panels) {
|
||||||
|
var mainPanel = p as MainPanel;
|
||||||
|
if (mainPanel) mainPanel.seedInputField.Set(dungeon.Generator.ChosenSeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdatePlusPanel() {
|
||||||
|
foreach(var p in panels) {
|
||||||
|
var plusPanel = p as DunGenPlusPanel;
|
||||||
|
if (plusPanel) plusPanel.UpdatePanel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateDungeonBounds(){
|
||||||
|
foreach(var p in panels) {
|
||||||
|
var plusPanel = p as DunGenPlusPanel;
|
||||||
|
if (plusPanel) plusPanel.UpdateDungeonBoundsHelper();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetAllDungeonFlows(){
|
||||||
|
dungeonFlows = LethalLevelLoader.PatchedContent.ExtendedDungeonFlows.ToArray();
|
||||||
|
dungeonFlowSelectionDropDown.options = dungeonFlows.Select(d => new TMP_Dropdown.OptionData(d.DungeonName)).ToList();
|
||||||
|
SelectDungeonFlow(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CacheMainCamera() {
|
||||||
|
var main = Camera.main;
|
||||||
|
if (main) {
|
||||||
|
lastMainCamera = main;
|
||||||
|
lastCameraPosition = main.transform.position;
|
||||||
|
lastCameraRotation = main.transform.rotation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BeginDevCamera(){
|
||||||
|
lastMainCamera?.gameObject.SetActive(false);
|
||||||
|
devCamera.SetActive(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EndDevCamera(){
|
||||||
|
devCamera.SetActive(false);
|
||||||
|
if (lastMainCamera) {
|
||||||
|
lastMainCamera.transform.position = lastCameraPosition;
|
||||||
|
lastMainCamera.transform.rotation = lastCameraRotation;
|
||||||
|
lastMainCamera.gameObject.SetActive(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
using DunGen;
|
||||||
|
using DunGenPlus.Collections;
|
||||||
|
using DunGenPlus.DevTools.Panels;
|
||||||
|
using DunGenPlus.DevTools.UIElements;
|
||||||
|
using LethalLevelLoader;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Dynamic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using TMPro;
|
||||||
|
using UnityEngine;
|
||||||
|
using static System.Collections.Specialized.BitVector32;
|
||||||
|
|
||||||
|
namespace DunGenPlus.DevTools {
|
||||||
|
|
||||||
|
internal partial class DevDebugManager : MonoBehaviour {
|
||||||
|
|
||||||
|
[Header("UI Prefabs")]
|
||||||
|
[Header("UI")]
|
||||||
|
public GameObject headerUIPrefab;
|
||||||
|
public GameObject textUIPrefab;
|
||||||
|
public GameObject spaceUIPrefab;
|
||||||
|
public GameObject verticalLayoutUIPrefab;
|
||||||
|
|
||||||
|
[Header("Input Fields")]
|
||||||
|
public GameObject intInputFieldPrefab;
|
||||||
|
public GameObject floatInputFieldPrefab;
|
||||||
|
public GameObject boolInputFieldPrefab;
|
||||||
|
public GameObject stringInputFieldPrefab;
|
||||||
|
public GameObject vector3InputFieldPrefab;
|
||||||
|
public GameObject intSliderFieldPrefab;
|
||||||
|
|
||||||
|
[Header("Special Fields")]
|
||||||
|
public GameObject listUIPrefab;
|
||||||
|
public GameObject optionsUIPrefab;
|
||||||
|
|
||||||
|
public TextUIElement CreateHeaderUIField(Transform parentTransform, string title, float offset) {
|
||||||
|
var gameObject = Instantiate(headerUIPrefab, parentTransform);
|
||||||
|
var field = gameObject.GetComponent<TextUIElement>();
|
||||||
|
field.SetupBase(title, offset);
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextUIElement CreateTextUIField(Transform parentTransform, string title, float offset) {
|
||||||
|
var gameObject = Instantiate(textUIPrefab, parentTransform);
|
||||||
|
var field = gameObject.GetComponent<TextUIElement>();
|
||||||
|
field.SetupBase(title, offset);
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreateSpaceUIField(Transform parentTransform) {
|
||||||
|
Instantiate(spaceUIPrefab, parentTransform);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transform CreateVerticalLayoutUIField(Transform parentTransform){
|
||||||
|
return Instantiate(verticalLayoutUIPrefab, parentTransform).transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntInputField CreateIntInputField(Transform parentTransform, string title, float offset, int baseValue, Action<int> setAction, int defaultValue = 0){
|
||||||
|
var gameObject = Instantiate(intInputFieldPrefab, parentTransform);
|
||||||
|
var field = gameObject.GetComponent<IntInputField>();
|
||||||
|
field.SetupInputField(title, offset, baseValue, setAction, defaultValue);
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FloatInputField CreateFloatInputField(Transform parentTransform, string title, float offset, float baseValue, Action<float> setAction, float defaultValue = 0f){
|
||||||
|
var gameObject = Instantiate(floatInputFieldPrefab, parentTransform);
|
||||||
|
var field = gameObject.GetComponent<FloatInputField>();
|
||||||
|
field.SetupInputField(title, offset, baseValue, setAction, defaultValue);
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BoolInputField CreateBoolInputField(Transform parentTransform, string title, float offset, bool baseValue, Action<bool> setAction){
|
||||||
|
var gameObject = Instantiate(boolInputFieldPrefab, parentTransform);
|
||||||
|
var field = gameObject.GetComponent<BoolInputField>();
|
||||||
|
field.SetupInputField(title, offset, baseValue, setAction, false);
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringInputField CreateStringInputField(Transform parentTransform, string title, float offset, string baseValue, Action<string> setAction){
|
||||||
|
var gameObject = Instantiate(stringInputFieldPrefab, parentTransform);
|
||||||
|
var field = gameObject.GetComponent<StringInputField>();
|
||||||
|
field.SetupInputField(title, offset, baseValue, setAction, string.Empty);
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3InputField CreateVector3InputField(Transform parentTransform, string title, float offset, Vector3 baseValue, Action<Vector3> setAction){
|
||||||
|
var gameObject = Instantiate(vector3InputFieldPrefab, parentTransform);
|
||||||
|
var field = gameObject.GetComponent<Vector3InputField>();
|
||||||
|
field.SetupInputField(title, offset, baseValue, setAction, Vector3.zero);
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntSliderField CreateIntSliderField(Transform parentTransform, string title, float offset, int baseValue, Action<int> setAction, int defaultValue = 0){
|
||||||
|
var gameObject = Instantiate(intSliderFieldPrefab, parentTransform);
|
||||||
|
var field = gameObject.GetComponent<IntSliderField>();
|
||||||
|
field.SetupInputField(title, offset, baseValue, setAction, defaultValue);
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListUIElement CreateListUIField<T>(Transform parentTransform, string title, float offset, List<T> list){
|
||||||
|
var gameObject = Instantiate(listUIPrefab, parentTransform);
|
||||||
|
var field = gameObject.GetComponent<ListUIElement>();
|
||||||
|
field.SetupList(title, offset, list);
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public DropdownInputField CreateOptionsUIField<T>(Transform parentTransform, string title, float offset, int baseValue, Action<T> setAction, Func<int, T> convertIndex, IEnumerable<string> options){
|
||||||
|
var gameObject = Instantiate(optionsUIPrefab, parentTransform);
|
||||||
|
var field = gameObject.GetComponent<DropdownInputField>();
|
||||||
|
field.SetupDropdown(title, offset, baseValue, setAction, convertIndex, options);
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DropdownInputField CreateLevelOptionsUIField(Transform parentTransform, string title, float offset, int baseValue, Action<ExtendedLevel> setAction){
|
||||||
|
var mainPanel = MainPanel.Instance;
|
||||||
|
return CreateOptionsUIField(parentTransform, title, offset, baseValue, setAction, (i) => mainPanel.levels[i], mainPanel.levelOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DropdownInputField CreateTileOptionsUIField(Transform parentTransform, string title, float offset, int baseValue, Action<GameObject> setAction){
|
||||||
|
var assetCache = DunGenPlusPanel.Instance.selectedAssetCache;
|
||||||
|
return CreateOptionsUIField(parentTransform, title, offset, baseValue, setAction, (i) => assetCache.tiles.list[i].Item, assetCache.tiles.options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DropdownInputField CreateArchetypeOptionsUIField(Transform parentTransform, string title, float offset, int baseValue, Action<DungeonArchetype> setAction){
|
||||||
|
var assetCache = DunGenPlusPanel.Instance.selectedAssetCache;
|
||||||
|
return CreateOptionsUIField(parentTransform, title, offset, baseValue, setAction, (i) => assetCache.archetypes.list[i].Item, assetCache.archetypes.options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DropdownInputField CreateCopyNodeBehaviourOptionsUIField(Transform parentTransform, string title, float offset, int baseValue, Action<DunGenExtenderProperties.CopyNodeBehaviour> setAction){
|
||||||
|
var options = Enum.GetNames(typeof(DunGenExtenderProperties.CopyNodeBehaviour));
|
||||||
|
return CreateOptionsUIField(parentTransform, title, offset, baseValue, setAction, (i) => (DunGenExtenderProperties.CopyNodeBehaviour)i, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.InputSystem;
|
||||||
|
using UnityEngine.InputSystem.Controls;
|
||||||
|
|
||||||
|
namespace DunGenPlus.DevTools {
|
||||||
|
internal class DevDebugOpen : MonoBehaviour {
|
||||||
|
|
||||||
|
public static bool IsSinglePlayerInShip(){
|
||||||
|
var startOfRound = StartOfRound.Instance;
|
||||||
|
var roundManager = RoundManager.Instance;
|
||||||
|
if (startOfRound && roundManager) {
|
||||||
|
return startOfRound.connectedPlayersAmount == 0 && startOfRound.inShipPhase;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(){
|
||||||
|
if (IfKeyPress(Keyboard.current.mKey) && DevDebugManager.Instance == null && IsSinglePlayerInShip()){
|
||||||
|
Instantiate(Assets.DevDebugPrefab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IfKeyPress(params KeyControl[] keys){
|
||||||
|
foreach(var k in keys){
|
||||||
|
if (k.wasPressedThisFrame) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace DunGenPlus.DevTools {
|
||||||
|
internal class PanelTab : MonoBehaviour {
|
||||||
|
public bool active;
|
||||||
|
|
||||||
|
[Header("References")]
|
||||||
|
public RectTransform rectTransform;
|
||||||
|
public Image image;
|
||||||
|
|
||||||
|
void Update() {
|
||||||
|
var targetHeight = active ? 48f : 36f;
|
||||||
|
var targetColor = active ? new Color(100f / 255f, 100f / 255f, 100f / 255f, 1f) : new Color(50f / 255f, 50f / 255f, 50f / 255f, 1f);
|
||||||
|
|
||||||
|
var size = rectTransform.sizeDelta;
|
||||||
|
size.y = Mathf.Lerp(size.y, targetHeight, Time.deltaTime * 10f);
|
||||||
|
rectTransform.sizeDelta = size;
|
||||||
|
|
||||||
|
var color = image.color;
|
||||||
|
color = Color.Lerp(color, targetColor, Time.deltaTime * 10f);
|
||||||
|
image.color = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
using DunGen;
|
||||||
|
using DunGen.Graph;
|
||||||
|
using LethalLevelLoader;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.Remoting.Messaging;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DunGenPlus.DevTools.Panels {
|
||||||
|
internal abstract class BasePanel : MonoBehaviour {
|
||||||
|
|
||||||
|
public DevDebugManager manager => DevDebugManager.Instance;
|
||||||
|
public RuntimeDungeon dungeon => manager.dungeon;
|
||||||
|
public ExtendedDungeonFlow selectedExtendedDungeonFlow => manager.selectedDungeonFlow;
|
||||||
|
public DungeonFlow selectedDungeonFlow => selectedExtendedDungeonFlow.DungeonFlow;
|
||||||
|
|
||||||
|
[Header("Renders")]
|
||||||
|
public GameObject mainGameObject;
|
||||||
|
public PanelTab tab;
|
||||||
|
|
||||||
|
public virtual void AwakeCall() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void SetPanelVisibility(bool visible) {
|
||||||
|
mainGameObject.SetActive(visible);
|
||||||
|
tab.active = visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int ParseTextInt(string text, int defaultValue = 0) {
|
||||||
|
if (int.TryParse(text, out var result)){
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
Plugin.logger.LogWarning($"Couldn't parse {text} into an int");
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected float ParseTextFloat(string text, float defaultValue = 0f) {
|
||||||
|
if (float.TryParse(text, out var result)){
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
Plugin.logger.LogWarning($"Couldn't parse {text} into a float");
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,258 @@
|
||||||
|
using DunGen;
|
||||||
|
using DunGen.Graph;
|
||||||
|
using DunGenPlus.Collections;
|
||||||
|
using LethalLevelLoader;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using TMPro;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using DunGenPlus.DevTools.UIElements;
|
||||||
|
|
||||||
|
namespace DunGenPlus.DevTools.Panels {
|
||||||
|
internal class DunGenPlusPanel : BasePanel {
|
||||||
|
|
||||||
|
public static DunGenPlusPanel Instance { get; private set; }
|
||||||
|
|
||||||
|
internal DungeonFlow previousDungeonFlow;
|
||||||
|
internal DunGenExtender selectedExtenderer;
|
||||||
|
internal DungeonFlowCacheAssets selectedAssetCache;
|
||||||
|
|
||||||
|
[Header("Panel References")]
|
||||||
|
public GameObject createGameObject;
|
||||||
|
public GameObject selectedGameObject;
|
||||||
|
|
||||||
|
[Header("Dungeon Bounds Helper")]
|
||||||
|
public GameObject dungeonBoundsHelperGameObject;
|
||||||
|
|
||||||
|
[Header("Selected Panel References")]
|
||||||
|
public Toggle activateDunGenPlusToggle;
|
||||||
|
|
||||||
|
private GameObject mainPathParentGameobject;
|
||||||
|
private GameObject dungeonBoundsParentGameobject;
|
||||||
|
private GameObject archetypesNodesParentGameobject;
|
||||||
|
|
||||||
|
public class DungeonFlowCacheAssets {
|
||||||
|
public DunGenExtenderProperties originalProperties;
|
||||||
|
|
||||||
|
public struct Collection<T> {
|
||||||
|
public List<T> list;
|
||||||
|
public Dictionary<T, int> dictionary;
|
||||||
|
public IEnumerable<string> options;
|
||||||
|
|
||||||
|
public Collection(List<T> list) {
|
||||||
|
this.list = list;
|
||||||
|
|
||||||
|
dictionary = new Dictionary<T, int>();
|
||||||
|
for(var i = 0; i < list.Count; i++) {
|
||||||
|
dictionary.Add(list[i], i);
|
||||||
|
}
|
||||||
|
|
||||||
|
options = list.Select(l => l.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<NullObject<TileSet>> tileSets;
|
||||||
|
public Collection<NullObject<GameObject>> tiles;
|
||||||
|
public Collection<NullObject<DungeonArchetype>> archetypes;
|
||||||
|
|
||||||
|
public DungeonFlowCacheAssets(DunGenExtender extender){
|
||||||
|
originalProperties = extender.Properties.Copy();
|
||||||
|
|
||||||
|
var tileSetsHashSet = new HashSet<NullObject<TileSet>>() { new NullObject<TileSet>(null) };
|
||||||
|
var tilesHashSet = new HashSet<NullObject<GameObject>>() { new NullObject<GameObject>(null) };
|
||||||
|
var archetypesHashSet = new HashSet<NullObject<DungeonArchetype>>() { new NullObject<DungeonArchetype>(null) };
|
||||||
|
|
||||||
|
foreach(var t in extender.DungeonFlow.Nodes) {
|
||||||
|
var label = t.Label.ToLowerInvariant();
|
||||||
|
if (label == "lchc gate" || label == "goal"){
|
||||||
|
foreach(var n in t.TileSets.SelectMany(x => x.TileWeights.Weights)) {
|
||||||
|
n.Value.GetComponent<Tile>().RepeatMode = TileRepeatMode.Allow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(var t in extender.DungeonFlow.Nodes.SelectMany(n => n.TileSets)) {
|
||||||
|
tileSetsHashSet.Add(t);
|
||||||
|
foreach(var x in t.TileWeights.Weights) {
|
||||||
|
tilesHashSet.Add(x.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach(var a in extender.DungeonFlow.Lines.SelectMany(l => l.DungeonArchetypes)) {
|
||||||
|
archetypesHashSet.Add(a);
|
||||||
|
foreach(var t in a.TileSets) {
|
||||||
|
tileSetsHashSet.Add(t);
|
||||||
|
foreach(var x in t.TileWeights.Weights) {
|
||||||
|
tilesHashSet.Add(x.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(var n in extender.Properties.NormalNodeArchetypes) {
|
||||||
|
foreach(var a in n.archetypes){
|
||||||
|
archetypesHashSet.Add(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tileSets = new Collection<NullObject<TileSet>>(tileSetsHashSet.ToList());
|
||||||
|
tiles = new Collection<NullObject<GameObject>>(tilesHashSet.ToList());
|
||||||
|
archetypes = new Collection<NullObject<DungeonArchetype>>(archetypesHashSet.ToList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<DungeonFlow, DungeonFlowCacheAssets> cacheDictionary = new Dictionary<DungeonFlow, DungeonFlowCacheAssets>();
|
||||||
|
|
||||||
|
public override void AwakeCall() {
|
||||||
|
Instance = this;
|
||||||
|
|
||||||
|
dungeonBoundsHelperGameObject.SetActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetPanelVisibility(bool visible) {
|
||||||
|
base.SetPanelVisibility(visible);
|
||||||
|
|
||||||
|
if (visible) UpdatePanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreateDunGenPlusExtenderer(){
|
||||||
|
var asset = API.CreateDunGenExtender(selectedDungeonFlow);
|
||||||
|
selectedDungeonFlow.TileInjectionRules = new List<TileInjectionRule>();
|
||||||
|
API.AddDunGenExtender(asset);
|
||||||
|
SetPanelVisibility(true);
|
||||||
|
UpdatePanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdatePanel(){
|
||||||
|
if (previousDungeonFlow == selectedDungeonFlow) return;
|
||||||
|
|
||||||
|
var hasAsset = API.ContainsDungeonFlow(selectedDungeonFlow);
|
||||||
|
selectedGameObject.SetActive(hasAsset);
|
||||||
|
createGameObject.SetActive(!hasAsset);
|
||||||
|
|
||||||
|
ClearPanel();
|
||||||
|
if (hasAsset) {
|
||||||
|
SetupPanel();
|
||||||
|
} else {
|
||||||
|
previousDungeonFlow = null;
|
||||||
|
selectedExtenderer = null;
|
||||||
|
selectedAssetCache = null;
|
||||||
|
dungeonBoundsHelperGameObject.SetActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetupPanel() {
|
||||||
|
var dungeonFlow = selectedDungeonFlow;
|
||||||
|
var extender = API.GetDunGenExtender(dungeonFlow);
|
||||||
|
if (!cacheDictionary.TryGetValue(dungeonFlow, out var cache)) {
|
||||||
|
cache = new DungeonFlowCacheAssets(extender);
|
||||||
|
cacheDictionary.Add(dungeonFlow, cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
previousDungeonFlow = dungeonFlow;
|
||||||
|
selectedExtenderer = extender;
|
||||||
|
selectedAssetCache = cache;
|
||||||
|
|
||||||
|
var parentTransform = selectedGameObject.transform;
|
||||||
|
var properties = selectedExtenderer.Properties;
|
||||||
|
manager.CreateBoolInputField(parentTransform, "Activate DunGenPlus", 0f, selectedExtenderer.Active, SetActivateDunGenPlus);
|
||||||
|
manager.CreateSpaceUIField(parentTransform);
|
||||||
|
|
||||||
|
var mainPathTransform = manager.CreateVerticalLayoutUIField(parentTransform);
|
||||||
|
mainPathParentGameobject = mainPathTransform.gameObject;
|
||||||
|
manager.CreateHeaderUIField(parentTransform, "Main Path", 0f);
|
||||||
|
manager.CreateIntSliderField(parentTransform, "Main Path Count", 0f, properties.MainPathCount, SetMainPathCount);
|
||||||
|
mainPathTransform.SetAsLastSibling();
|
||||||
|
manager.CreateTileOptionsUIField(mainPathTransform, "Main Room Tile Prefab", 0f, selectedAssetCache.tiles.dictionary[properties.MainRoomTilePrefab], SetMainRoom);
|
||||||
|
manager.CreateCopyNodeBehaviourOptionsUIField(mainPathTransform, "Copy Node Behaviour", 0f, (int)properties.MainPathCopyNodeBehaviour, SetCopyNodeBehaviour);
|
||||||
|
manager.CreateSpaceUIField(parentTransform);
|
||||||
|
|
||||||
|
var dungeonBoundsTransform = manager.CreateVerticalLayoutUIField(parentTransform);
|
||||||
|
dungeonBoundsParentGameobject = dungeonBoundsTransform.gameObject;
|
||||||
|
manager.CreateHeaderUIField(parentTransform, "Dungeon Bounds", 0f);
|
||||||
|
manager.CreateBoolInputField(parentTransform, "Use Dungeon Bounds", 0f, properties.UseDungeonBounds, SetUseDungeonBounds);
|
||||||
|
dungeonBoundsTransform.SetAsLastSibling();
|
||||||
|
manager.CreateVector3InputField(dungeonBoundsTransform, "Size Base", 0f, properties.DungeonSizeBase, SetDungeonBoundsSizeBase);
|
||||||
|
manager.CreateVector3InputField(dungeonBoundsTransform, "Size Factor", 0f, properties.DungeonSizeFactor, SetDungeonBoundsSizeFactor);
|
||||||
|
manager.CreateVector3InputField(dungeonBoundsTransform, "Position Offset", 0f, properties.DungeonPositionOffset, SetDungeonBoundsPosOffset);
|
||||||
|
manager.CreateVector3InputField(dungeonBoundsTransform, "Position Pivot", 0f, properties.DungeonPositionPivot, SetDungeonBoundsPosPivot);
|
||||||
|
manager.CreateSpaceUIField(parentTransform);
|
||||||
|
|
||||||
|
var archetypesTransform = manager.CreateVerticalLayoutUIField(parentTransform);
|
||||||
|
archetypesNodesParentGameobject = archetypesTransform.gameObject;
|
||||||
|
manager.CreateHeaderUIField(parentTransform, "Archetypes Normal Nodes", 0f);
|
||||||
|
manager.CreateBoolInputField(parentTransform, "Add Archetypes", 0f, properties.AddArchetypesToNormalNodes, SetAddArchetypes);
|
||||||
|
archetypesTransform.SetAsLastSibling();
|
||||||
|
manager.CreateListUIField(archetypesTransform, "Normal Node Archetypes", 0f, properties.NormalNodeArchetypes);
|
||||||
|
manager.CreateSpaceUIField(parentTransform);
|
||||||
|
|
||||||
|
dungeonBoundsHelperGameObject.SetActive(selectedExtenderer.Properties.UseDungeonBounds);
|
||||||
|
UpdateDungeonBoundsHelper();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearPanel(){
|
||||||
|
manager.ClearTransformChildren(selectedGameObject.transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetActivateDunGenPlus(bool state){
|
||||||
|
selectedExtenderer.Active = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetMainPathCount(int value) {
|
||||||
|
selectedExtenderer.Properties.MainPathCount = value;
|
||||||
|
mainPathParentGameobject.SetActive(value > 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetMainRoom(GameObject value) {
|
||||||
|
selectedExtenderer.Properties.MainRoomTilePrefab = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetCopyNodeBehaviour(DunGenExtenderProperties.CopyNodeBehaviour value) {
|
||||||
|
selectedExtenderer.Properties.MainPathCopyNodeBehaviour = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetUseDungeonBounds(bool state){
|
||||||
|
selectedExtenderer.Properties.UseDungeonBounds = state;
|
||||||
|
dungeonBoundsHelperGameObject.SetActive(state);
|
||||||
|
dungeonBoundsParentGameobject.SetActive(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateDungeonBoundsHelper(){
|
||||||
|
if (selectedExtenderer == null) return;
|
||||||
|
|
||||||
|
var t = dungeonBoundsHelperGameObject.transform;
|
||||||
|
var result = selectedExtenderer.Properties.GetDungeonBounds(dungeon.Generator.LengthMultiplier);
|
||||||
|
t.localPosition = result.center;
|
||||||
|
t.localScale = result.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetDungeonBoundsSizeBase(Vector3 value) {
|
||||||
|
selectedExtenderer.Properties.DungeonSizeBase = value;
|
||||||
|
UpdateDungeonBoundsHelper();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetDungeonBoundsSizeFactor(Vector3 value) {
|
||||||
|
selectedExtenderer.Properties.DungeonSizeFactor = value;
|
||||||
|
UpdateDungeonBoundsHelper();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetDungeonBoundsPosOffset(Vector3 value) {
|
||||||
|
selectedExtenderer.Properties.DungeonPositionOffset = value;
|
||||||
|
UpdateDungeonBoundsHelper();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetDungeonBoundsPosPivot(Vector3 value) {
|
||||||
|
selectedExtenderer.Properties.DungeonPositionPivot = value;
|
||||||
|
UpdateDungeonBoundsHelper();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetAddArchetypes(bool state){
|
||||||
|
selectedExtenderer.Properties.AddArchetypesToNormalNodes = state;
|
||||||
|
archetypesNodesParentGameobject.SetActive(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
using DunGen;
|
||||||
|
using DunGenPlus.DevTools.UIElements;
|
||||||
|
using LethalLevelLoader;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using TMPro;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace DunGenPlus.DevTools.Panels {
|
||||||
|
internal class MainPanel : BasePanel {
|
||||||
|
|
||||||
|
public static MainPanel Instance { get; private set; }
|
||||||
|
|
||||||
|
internal IntInputField seedInputField;
|
||||||
|
internal TextUIElement lengthMultiplierField;
|
||||||
|
|
||||||
|
internal ExtendedLevel[] levels;
|
||||||
|
internal IEnumerable<string> levelOptions;
|
||||||
|
|
||||||
|
public override void AwakeCall(){
|
||||||
|
Instance = this;
|
||||||
|
|
||||||
|
GetAllLevels();
|
||||||
|
|
||||||
|
var gen = dungeon.Generator;
|
||||||
|
var parentTransform = mainGameObject.transform;
|
||||||
|
|
||||||
|
manager.CreateHeaderUIField(parentTransform, "Dungeon Generator", 0f);
|
||||||
|
seedInputField = manager.CreateIntInputField(parentTransform, "Seed", 0f, gen.Seed, SetSeed);
|
||||||
|
manager.CreateBoolInputField(parentTransform, "Randomize Seed", 0f, gen.ShouldRandomizeSeed, SetRandomSeed);
|
||||||
|
manager.CreateSpaceUIField(parentTransform);
|
||||||
|
|
||||||
|
manager.CreateIntInputField(parentTransform, "Max Attempts", 0f, gen.MaxAttemptCount, SetMaxAttempts, 10);
|
||||||
|
manager.CreateSpaceUIField(parentTransform);
|
||||||
|
|
||||||
|
manager.CreateBoolInputField(parentTransform, "Generate Async", 0f, gen.GenerateAsynchronously, SetGenerateAsync);
|
||||||
|
manager.CreateFloatInputField(parentTransform, "Max Async (ms)", 0f, gen.MaxAsyncFrameMilliseconds, SetMaxAsync);
|
||||||
|
manager.CreateFloatInputField(parentTransform, "Pause Betwoon Rooms", 0f, gen.PauseBetweenRooms, SetPauseBetweenRooms);
|
||||||
|
manager.CreateSpaceUIField(parentTransform);
|
||||||
|
|
||||||
|
manager.CreateHeaderUIField(parentTransform, "Levels", 0f);
|
||||||
|
manager.CreateLevelOptionsUIField(parentTransform, "Level", 0f, 0, SetLevel);
|
||||||
|
lengthMultiplierField = manager.CreateTextUIField(parentTransform, "Length Multiplier", 0f);
|
||||||
|
SetLevel(levels[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetSeed(int value) {
|
||||||
|
dungeon.Generator.Seed = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetRandomSeed(bool state) {
|
||||||
|
dungeon.Generator.ShouldRandomizeSeed = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetMaxAttempts(int value) {
|
||||||
|
dungeon.Generator.MaxAttemptCount = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetGenerateAsync(bool state) {
|
||||||
|
dungeon.Generator.GenerateAsynchronously = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetMaxAsync(float value) {
|
||||||
|
dungeon.Generator.MaxAsyncFrameMilliseconds = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetPauseBetweenRooms(float value) {
|
||||||
|
dungeon.Generator.PauseBetweenRooms = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetAllLevels(){
|
||||||
|
levels = LethalLevelLoader.PatchedContent.ExtendedLevels.ToArray();
|
||||||
|
levelOptions = levels.Select(l => l.NumberlessPlanetName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetLevel(ExtendedLevel level){
|
||||||
|
var currentLevelLengthMultlpier = GetLevelMultiplier(level);
|
||||||
|
dungeon.Generator.LengthMultiplier = currentLevelLengthMultlpier;
|
||||||
|
manager.UpdateDungeonBounds();
|
||||||
|
lengthMultiplierField.SetText($"Length multiplier: {currentLevelLengthMultlpier.ToString("F2")}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private float GetLevelMultiplier(ExtendedLevel level){
|
||||||
|
var roundManager = RoundManager.Instance;
|
||||||
|
if (roundManager == null) {
|
||||||
|
Plugin.logger.LogError("RoundManager somehow null. Can't set level length multiplier");
|
||||||
|
return 1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return roundManager.mapSizeMultiplier * level.SelectableLevel.factorySizeMultiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace DunGenPlus.DevTools.UIElements {
|
||||||
|
internal abstract class BaseInputField<T> : BaseUIElement {
|
||||||
|
|
||||||
|
public virtual void SetupInputField(string titleText, float offset, T baseValue, Action<T> setAction, T defaultValue){
|
||||||
|
SetupBase(titleText, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void Set(T value);
|
||||||
|
|
||||||
|
protected int ParseTextInt(string text, int defaultValue = 0) {
|
||||||
|
if (int.TryParse(text, out var result)){
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
Plugin.logger.LogWarning($"Couldn't parse {text} into an int");
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected float ParseTextFloat(string text, float defaultValue = 0f) {
|
||||||
|
if (float.TryParse(text, out var result)){
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
Plugin.logger.LogWarning($"Couldn't parse {text} into a float");
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using TMPro;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace DunGenPlus.DevTools.UIElements {
|
||||||
|
internal abstract class BaseUIElement : MonoBehaviour {
|
||||||
|
|
||||||
|
public TextMeshProUGUI titleTextMesh;
|
||||||
|
internal string title;
|
||||||
|
|
||||||
|
public LayoutElement layoutElement;
|
||||||
|
internal float layoutOffset;
|
||||||
|
|
||||||
|
public void SetupBase(string titleText, float offset) {
|
||||||
|
title = titleText;
|
||||||
|
SetText(title);
|
||||||
|
|
||||||
|
layoutOffset = offset;
|
||||||
|
if (layoutElement) {
|
||||||
|
layoutElement.minWidth -= layoutOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetText(string value) {
|
||||||
|
titleTextMesh.text = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using TMPro;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace DunGenPlus.DevTools.UIElements {
|
||||||
|
internal class BoolInputField : BaseInputField<bool> {
|
||||||
|
|
||||||
|
public Toggle toggle;
|
||||||
|
|
||||||
|
public override void SetupInputField(string title, float offset, bool baseValue, Action<bool> setAction, bool defaultValue) {
|
||||||
|
base.SetupInputField(title, offset, baseValue, setAction, defaultValue);
|
||||||
|
|
||||||
|
toggle.onValueChanged.AddListener((t) => SetValue(setAction, t));
|
||||||
|
Set(baseValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetValue(Action<bool> setAction, bool state) {
|
||||||
|
Plugin.logger.LogInfo($"Setting {title} to {state}");
|
||||||
|
setAction.Invoke(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Set(bool state){
|
||||||
|
toggle.isOn = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using TMPro;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace DunGenPlus.DevTools.UIElements
|
||||||
|
{
|
||||||
|
internal class DropdownInputField : BaseUIElement {
|
||||||
|
|
||||||
|
public TMP_Dropdown dropDown;
|
||||||
|
|
||||||
|
public void SetupDropdown<T>(string titleText, float offset, int baseValue, Action<T> setAction, Func<int, T> convertIndex, IEnumerable<string> options) {
|
||||||
|
SetupBase(titleText, offset);
|
||||||
|
|
||||||
|
dropDown.options = options.Select(c => {
|
||||||
|
return new TMP_Dropdown.OptionData(c.Substring(0, Math.Min(24, c.Length)));
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
dropDown.onValueChanged.AddListener((t) => SetValue(setAction, convertIndex, t));
|
||||||
|
dropDown.value = baseValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetValue<T>(Action<T> setAction, Func<int, T> convertIndex, int index) {
|
||||||
|
var value = convertIndex.Invoke(index);
|
||||||
|
Plugin.logger.LogInfo($"Setting {title} to {value}");
|
||||||
|
setAction.Invoke(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using TMPro;
|
||||||
|
|
||||||
|
namespace DunGenPlus.DevTools.UIElements
|
||||||
|
{
|
||||||
|
internal class FloatInputField : BaseInputField<float> {
|
||||||
|
|
||||||
|
public TMP_InputField inputField;
|
||||||
|
internal float defaultValue = 0f;
|
||||||
|
|
||||||
|
public override void SetupInputField(string title, float offset, float baseValue, Action<float> setAction , float defaultValue) {
|
||||||
|
base.SetupInputField(title, offset, baseValue, setAction, defaultValue);
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
|
||||||
|
inputField.onValueChanged.AddListener((t) => SetValue(setAction, t));
|
||||||
|
Set(baseValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetValue(Action<float> setAction, string text) {
|
||||||
|
Plugin.logger.LogInfo($"Setting {title} to {text}");
|
||||||
|
setAction.Invoke(ParseTextFloat(text, defaultValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Set(float value){
|
||||||
|
inputField.text = value.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using TMPro;
|
||||||
|
|
||||||
|
namespace DunGenPlus.DevTools.UIElements {
|
||||||
|
internal class IntInputField : BaseInputField<int> {
|
||||||
|
|
||||||
|
public TMP_InputField inputField;
|
||||||
|
internal int defaultValue = 0;
|
||||||
|
|
||||||
|
public override void SetupInputField(string title, float offset, int baseValue, Action<int> setAction , int defaultValue) {
|
||||||
|
base.SetupInputField(title, offset, baseValue, setAction, defaultValue);
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
|
||||||
|
inputField.onValueChanged.AddListener((t) => SetValue(setAction, t));
|
||||||
|
Set(baseValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetValue(Action<int> setAction, string text) {
|
||||||
|
Plugin.logger.LogInfo($"Setting {title} to {text}");
|
||||||
|
setAction.Invoke(ParseTextInt(text, defaultValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Set(int value){
|
||||||
|
inputField.text = value.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using TMPro;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace DunGenPlus.DevTools.UIElements {
|
||||||
|
|
||||||
|
internal class IntSliderField : BaseInputField<int> {
|
||||||
|
|
||||||
|
public Slider inputField;
|
||||||
|
public TextMeshProUGUI textMesh;
|
||||||
|
internal int defaultValue = 0;
|
||||||
|
|
||||||
|
public override void SetupInputField(string title, float offset, int baseValue, Action<int> setAction , int defaultValue) {
|
||||||
|
base.SetupInputField(title, offset, baseValue, setAction, defaultValue);
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
|
||||||
|
inputField.onValueChanged.AddListener((t) => SetValue(setAction, t));
|
||||||
|
Set(baseValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetValue(Action<int> setAction, float value) {
|
||||||
|
Plugin.logger.LogInfo($"Setting {title} to {value}");
|
||||||
|
setAction.Invoke((int)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Set(int value){
|
||||||
|
inputField.value = value;
|
||||||
|
textMesh.text = value.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
using DunGen;
|
||||||
|
using DunGenPlus.Collections;
|
||||||
|
using DunGenPlus.DevTools.Panels;
|
||||||
|
using LethalLevelLoader;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using TMPro;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DunGenPlus.DevTools.UIElements {
|
||||||
|
internal class ListUIElement : BaseUIElement {
|
||||||
|
|
||||||
|
public GameObject templatePrefab;
|
||||||
|
public Transform listTransform;
|
||||||
|
|
||||||
|
internal IList list;
|
||||||
|
internal Type listType;
|
||||||
|
|
||||||
|
public void SetupList<T>(string titleText, float offset, List<T> list) {
|
||||||
|
SetupBase(titleText, offset);
|
||||||
|
|
||||||
|
this.list = list;
|
||||||
|
listType = typeof(T);
|
||||||
|
for(var i = 0; i < list.Count; ++i) {
|
||||||
|
CreateEntry(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddElement() {
|
||||||
|
object item = null;
|
||||||
|
if (listType == typeof(DungeonArchetype)) {
|
||||||
|
item = null;
|
||||||
|
} else if (listType == typeof(NodeArchetype)) {
|
||||||
|
item = new NodeArchetype();
|
||||||
|
}
|
||||||
|
|
||||||
|
list.Add(item);
|
||||||
|
CreateEntry(list.Count - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveElement(){
|
||||||
|
if (list.Count == 0) return;
|
||||||
|
list.RemoveAt(list.Count - 1);
|
||||||
|
Destroy(listTransform.GetChild(listTransform.childCount - 1).gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreateEntry(int index){
|
||||||
|
var copy = CreateCopy(index);
|
||||||
|
var copyParentTransform = copy.transform.Find("Items");
|
||||||
|
|
||||||
|
if (listType == typeof(DungeonArchetype)){
|
||||||
|
var entry = (DungeonArchetype)list[index];
|
||||||
|
var baseValue = DunGenPlusPanel.Instance.selectedAssetCache.archetypes.dictionary[entry];
|
||||||
|
DevDebugManager.Instance.CreateArchetypeOptionsUIField(copyParentTransform, "Archetype", layoutOffset + 24f, baseValue, (t) => list[index] = t);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (listType == typeof(NodeArchetype)) {
|
||||||
|
var entry = (NodeArchetype)list[index];
|
||||||
|
DevDebugManager.Instance.CreateStringInputField(copyParentTransform, "Label", layoutOffset + 24f, entry.label, (t) => entry.label = t);
|
||||||
|
DevDebugManager.Instance.CreateListUIField(copyParentTransform, "Archetypes", layoutOffset + 24f, entry.archetypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
copy.SetActive(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameObject CreateCopy(int index){
|
||||||
|
var copy = Instantiate(templatePrefab, listTransform);
|
||||||
|
copy.transform.Find("Element").GetComponent<TextMeshProUGUI>().text = $"Element {index}";
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using TMPro;
|
||||||
|
|
||||||
|
namespace DunGenPlus.DevTools.UIElements
|
||||||
|
{
|
||||||
|
internal class StringInputField : BaseInputField<string> {
|
||||||
|
|
||||||
|
public TMP_InputField inputField;
|
||||||
|
|
||||||
|
public override void SetupInputField(string title, float offset, string baseValue, Action<string> setAction, string defaultValue) {
|
||||||
|
base.SetupInputField(title, offset, baseValue, setAction, defaultValue);
|
||||||
|
|
||||||
|
inputField.onValueChanged.AddListener((t) => SetValue(setAction, t));
|
||||||
|
Set(baseValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetValue(Action<string> setAction, string text) {
|
||||||
|
Plugin.logger.LogInfo($"Setting {title} to {text}");
|
||||||
|
setAction.Invoke(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Set(string value){
|
||||||
|
inputField.text = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DunGenPlus.DevTools.UIElements {
|
||||||
|
internal class TextUIElement : BaseUIElement {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using TMPro;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Events;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace DunGenPlus.DevTools.UIElements {
|
||||||
|
|
||||||
|
internal class Vector3InputField : BaseInputField<Vector3> {
|
||||||
|
|
||||||
|
public TMP_InputField xInputField;
|
||||||
|
public TMP_InputField yInputField;
|
||||||
|
public TMP_InputField zInputField;
|
||||||
|
private Vector3 _value;
|
||||||
|
|
||||||
|
public override void SetupInputField(string titleText, float offset, Vector3 baseValue, Action<Vector3> setAction, Vector3 defaultValue) {
|
||||||
|
base.SetupInputField(titleText, offset, baseValue, setAction, defaultValue);
|
||||||
|
|
||||||
|
xInputField.onValueChanged.AddListener((t) => SetXValue(setAction, t));
|
||||||
|
yInputField.onValueChanged.AddListener((t) => SetYValue(setAction, t));
|
||||||
|
zInputField.onValueChanged.AddListener((t) => SetZValue(setAction, t));
|
||||||
|
|
||||||
|
Set(baseValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetXValue(Action<Vector3> setAction, string text){
|
||||||
|
Plugin.logger.LogInfo($"Setting {title}.x to {text}");
|
||||||
|
_value.x = ParseTextFloat(text);
|
||||||
|
setAction.Invoke(_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetYValue(Action<Vector3> setAction, string text){
|
||||||
|
Plugin.logger.LogInfo($"Setting {title}.y to {text}");
|
||||||
|
_value.y = ParseTextFloat(text);
|
||||||
|
setAction.Invoke(_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetZValue(Action<Vector3> setAction, string text){
|
||||||
|
Plugin.logger.LogInfo($"Setting {title}.z to {text}");
|
||||||
|
_value.z = ParseTextFloat(text);
|
||||||
|
setAction.Invoke(_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Set(Vector3 value){
|
||||||
|
_value = value;
|
||||||
|
xInputField.text = value.x.ToString();
|
||||||
|
yInputField.text = value.y.ToString();
|
||||||
|
zInputField.text = value.z.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ namespace DunGenPlus {
|
||||||
|
|
||||||
[Header("DEV ONLY: DON'T TOUCH")]
|
[Header("DEV ONLY: DON'T TOUCH")]
|
||||||
public string Version = "0";
|
public string Version = "0";
|
||||||
|
internal bool Active = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,8 +46,8 @@
|
||||||
<Reference Include="BepInEx.Harmony">
|
<Reference Include="BepInEx.Harmony">
|
||||||
<HintPath>..\..\..\Libraries\BepInEx.Harmony.dll</HintPath>
|
<HintPath>..\..\..\Libraries\BepInEx.Harmony.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="LethalLevelLoader">
|
<Reference Include="LethalLevelLoader-publicized">
|
||||||
<HintPath>..\..\..\Libraries\LethalLevelLoader.dll</HintPath>
|
<HintPath>..\..\..\Libraries\LethalLevelLoader-publicized.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
@ -60,6 +60,10 @@
|
||||||
<Reference Include="Unity.Collections">
|
<Reference Include="Unity.Collections">
|
||||||
<HintPath>..\..\..\Libraries\Unity.Collections.dll</HintPath>
|
<HintPath>..\..\..\Libraries\Unity.Collections.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Unity.InputSystem, Version=1.7.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\..\Libraries\Unity.InputSystem.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Unity.Netcode.Components, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Unity.Netcode.Components, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\..\..\Libraries\Unity.Netcode.Components.dll</HintPath>
|
<HintPath>..\..\..\Libraries\Unity.Netcode.Components.dll</HintPath>
|
||||||
|
@ -80,6 +84,10 @@
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\..\..\Libraries\Unity.RenderPipelines.HighDefinition.Runtime.dll</HintPath>
|
<HintPath>..\..\..\Libraries\Unity.RenderPipelines.HighDefinition.Runtime.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Unity.TextMeshPro, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\..\Libraries\Unity.TextMeshPro.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="UnityEngine">
|
<Reference Include="UnityEngine">
|
||||||
<HintPath>..\..\..\Libraries\UnityEngine.dll</HintPath>
|
<HintPath>..\..\..\Libraries\UnityEngine.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
@ -90,6 +98,33 @@
|
||||||
<Reference Include="UnityEngine.CoreModule">
|
<Reference Include="UnityEngine.CoreModule">
|
||||||
<HintPath>..\..\..\Libraries\UnityEngine.CoreModule.dll</HintPath>
|
<HintPath>..\..\..\Libraries\UnityEngine.CoreModule.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.IMGUIModule, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\..\Libraries\UnityEngine.IMGUIModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.InputLegacyModule, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\..\Libraries\UnityEngine.InputLegacyModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.InputModule, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\..\Libraries\UnityEngine.InputModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UI, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\..\Libraries\UnityEngine.UI.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UIElementsModule, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\..\Libraries\UnityEngine.UIElementsModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UIElementsNativeModule">
|
||||||
|
<HintPath>..\..\..\Libraries\UnityEngine.UIElementsNativeModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UIModule, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\..\Libraries\UnityEngine.UIModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="API.cs" />
|
<Compile Include="API.cs" />
|
||||||
|
@ -98,6 +133,7 @@
|
||||||
<Compile Include="Collections\ExtenderEvent.cs" />
|
<Compile Include="Collections\ExtenderEvent.cs" />
|
||||||
<Compile Include="Collections\ForcedTileSetList.cs" />
|
<Compile Include="Collections\ForcedTileSetList.cs" />
|
||||||
<Compile Include="Collections\NodeArchetype.cs" />
|
<Compile Include="Collections\NodeArchetype.cs" />
|
||||||
|
<Compile Include="Collections\NullObject.cs" />
|
||||||
<Compile Include="Components\DoorwayCleanup.cs" />
|
<Compile Include="Components\DoorwayCleanup.cs" />
|
||||||
<Compile Include="Components\DoorwayCleanupScripting\DCSRemoveDoorwayConnectedDoorway.cs" />
|
<Compile Include="Components\DoorwayCleanupScripting\DCSRemoveDoorwayConnectedDoorway.cs" />
|
||||||
<Compile Include="Components\DoorwayCleanupScripting\DCSRemoveDoorwaySpawnedPrefab.cs" />
|
<Compile Include="Components\DoorwayCleanupScripting\DCSRemoveDoorwaySpawnedPrefab.cs" />
|
||||||
|
@ -109,6 +145,24 @@
|
||||||
<Compile Include="Components\MainRoomDoorwayGroups.cs" />
|
<Compile Include="Components\MainRoomDoorwayGroups.cs" />
|
||||||
<Compile Include="Components\Props\SpawnSyncedObjectCycle.cs" />
|
<Compile Include="Components\Props\SpawnSyncedObjectCycle.cs" />
|
||||||
<Compile Include="Components\Scrap\RandomGuaranteedScrapSpawn.cs" />
|
<Compile Include="Components\Scrap\RandomGuaranteedScrapSpawn.cs" />
|
||||||
|
<Compile Include="DevTools\DevDebugManager.cs" />
|
||||||
|
<Compile Include="DevTools\DevDebugManagerUI.cs" />
|
||||||
|
<Compile Include="DevTools\DevDebugOpen.cs" />
|
||||||
|
<Compile Include="DevTools\Panels\BasePanel.cs" />
|
||||||
|
<Compile Include="DevTools\Panels\DunGenPlusPanel.cs" />
|
||||||
|
<Compile Include="DevTools\Panels\MainPanel.cs" />
|
||||||
|
<Compile Include="DevTools\PanelTab.cs" />
|
||||||
|
<Compile Include="DevTools\UIElements\BaseInputField.cs" />
|
||||||
|
<Compile Include="DevTools\UIElements\BaseUIElement.cs" />
|
||||||
|
<Compile Include="DevTools\UIElements\BoolInputField.cs" />
|
||||||
|
<Compile Include="DevTools\UIElements\DropdownInputField.cs" />
|
||||||
|
<Compile Include="DevTools\UIElements\FloatInputField.cs" />
|
||||||
|
<Compile Include="DevTools\UIElements\IntInputField.cs" />
|
||||||
|
<Compile Include="DevTools\UIElements\IntSliderField.cs" />
|
||||||
|
<Compile Include="DevTools\UIElements\ListUIElement.cs" />
|
||||||
|
<Compile Include="DevTools\UIElements\StringInputField.cs" />
|
||||||
|
<Compile Include="DevTools\UIElements\TextUIElement.cs" />
|
||||||
|
<Compile Include="DevTools\UIElements\Vector3InputField.cs" />
|
||||||
<Compile Include="DunGenExtender.cs" />
|
<Compile Include="DunGenExtender.cs" />
|
||||||
<Compile Include="Collections\DunGenExtenderProperties.cs" />
|
<Compile Include="Collections\DunGenExtenderProperties.cs" />
|
||||||
<Compile Include="Generation\DunGenPlusGenerator.cs" />
|
<Compile Include="Generation\DunGenPlusGenerator.cs" />
|
||||||
|
@ -116,6 +170,7 @@
|
||||||
<Compile Include="Patches\DoorwayConnectionPatch.cs" />
|
<Compile Include="Patches\DoorwayConnectionPatch.cs" />
|
||||||
<Compile Include="Generation\DoorwaySistersRule.cs" />
|
<Compile Include="Generation\DoorwaySistersRule.cs" />
|
||||||
<Compile Include="Patches\DungeonGeneratorPatch.cs" />
|
<Compile Include="Patches\DungeonGeneratorPatch.cs" />
|
||||||
|
<Compile Include="Patches\LethalLevelLoaderPatches.cs" />
|
||||||
<Compile Include="Patches\RoundManagerPatch.cs" />
|
<Compile Include="Patches\RoundManagerPatch.cs" />
|
||||||
<Compile Include="Patches\StartOfRoundPatch.cs" />
|
<Compile Include="Patches\StartOfRoundPatch.cs" />
|
||||||
<Compile Include="Plugin.cs" />
|
<Compile Include="Plugin.cs" />
|
||||||
|
@ -124,8 +179,17 @@
|
||||||
<Compile Include="Utils\Utility.cs" />
|
<Compile Include="Utils\Utility.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
<ItemGroup />
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="dungen" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="dungen" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PostBuildEvent>copy "$(TargetPath)" "C:\Users\Jose Garcia\AppData\Roaming\r2modmanPlus-local\LethalCompany\profiles\SDM Debug\BepInEx\plugins\Alice-DungeonGenerationPlus\$(TargetName).dll"</PostBuildEvent>
|
<PostBuildEvent>copy "$(TargetPath)" "C:\Users\Jose Garcia\AppData\Roaming\r2modmanPlus-local\LethalCompany\profiles\SDM Debug\BepInEx\plugins\Alice-DungeonGenerationPlus\$(TargetName).dll"</PostBuildEvent>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<PreBuildEvent>copy "D:\Previous Computer\Desktop\LethalCompany Modding\Unity Template\Assets\AssetBundles\dungen" "$(ProjectDir)\dungen"</PreBuildEvent>
|
||||||
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -0,0 +1,20 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using DunGenPlus.DevTools;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
|
||||||
|
namespace DunGenPlus.Patches {
|
||||||
|
internal class LethalLevelLoaderPatches {
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(LethalLevelLoader.Patches), "DungeonGeneratorGenerate_Prefix")]
|
||||||
|
public static bool DungeonGeneratorGenerate_Prefix_Prefix(){
|
||||||
|
return DevDebugManager.Instance == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
using DunGen;
|
using DunGen;
|
||||||
using DunGenPlus.Components.Scrap;
|
using DunGenPlus.Components.Scrap;
|
||||||
|
using DunGenPlus.DevTools;
|
||||||
using DunGenPlus.Generation;
|
using DunGenPlus.Generation;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using System;
|
using System;
|
||||||
|
@ -9,10 +10,17 @@ using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Unity.Netcode;
|
using Unity.Netcode;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace DunGenPlus.Patches {
|
namespace DunGenPlus.Patches {
|
||||||
public class RoundManagerPatch {
|
public class RoundManagerPatch {
|
||||||
|
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(typeof(RoundManager), "Awake")]
|
||||||
|
public static void AwakePatch(){
|
||||||
|
var devDebug = new GameObject("DevDebugOpen", typeof(DevDebugOpen));
|
||||||
|
}
|
||||||
|
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(typeof(RoundManager), "waitForScrapToSpawnToSync")]
|
[HarmonyPatch(typeof(RoundManager), "waitForScrapToSpawnToSync")]
|
||||||
public static void waitForScrapToSpawnToSyncPatch (ref RoundManager __instance, ref NetworkObjectReference[] spawnedScrap, ref int[] scrapValues) {
|
public static void waitForScrapToSpawnToSyncPatch (ref RoundManager __instance, ref NetworkObjectReference[] spawnedScrap, ref int[] scrapValues) {
|
||||||
|
|
|
@ -19,6 +19,7 @@ using UnityEngine.Assertions;
|
||||||
namespace DunGenPlus {
|
namespace DunGenPlus {
|
||||||
|
|
||||||
[BepInPlugin(modGUID, modName, modVersion)]
|
[BepInPlugin(modGUID, modName, modVersion)]
|
||||||
|
[BepInDependency("imabatby.lethallevelloader", "1.2.0.3")]
|
||||||
[BepInProcess("Lethal Company.exe")]
|
[BepInProcess("Lethal Company.exe")]
|
||||||
public class Plugin : BaseUnityPlugin {
|
public class Plugin : BaseUnityPlugin {
|
||||||
|
|
||||||
|
@ -44,9 +45,17 @@ namespace DunGenPlus {
|
||||||
Harmony.PatchAll(typeof(DoorwayConnectionPatch));
|
Harmony.PatchAll(typeof(DoorwayConnectionPatch));
|
||||||
Harmony.PatchAll(typeof(RoundManagerPatch));
|
Harmony.PatchAll(typeof(RoundManagerPatch));
|
||||||
|
|
||||||
|
try {
|
||||||
|
Harmony.PatchAll(typeof(LethalLevelLoaderPatches));
|
||||||
|
} catch (Exception e) {
|
||||||
|
Plugin.logger.LogError("Failed to patch LLL for dev debug. You can ignore this.");
|
||||||
|
Plugin.logger.LogError(e);
|
||||||
|
}
|
||||||
|
|
||||||
//Harmony.PatchAll(typeof(StartOfRoundPatch));
|
//Harmony.PatchAll(typeof(StartOfRoundPatch));
|
||||||
|
|
||||||
Assets.LoadAssets();
|
Assets.LoadAssets();
|
||||||
|
Assets.LoadAssetBundle();
|
||||||
DungeonManager.GlobalDungeonEvents.onBeforeDungeonGenerate.AddListener(OnDunGenExtenderLoad);
|
DungeonManager.GlobalDungeonEvents.onBeforeDungeonGenerate.AddListener(OnDunGenExtenderLoad);
|
||||||
DoorwayManager.onMainEntranceTeleportSpawnedEvent.AddEvent("DoorwayCleanup", DoorwayManager.onMainEntranceTeleportSpawnedFunction);
|
DoorwayManager.onMainEntranceTeleportSpawnedEvent.AddEvent("DoorwayCleanup", DoorwayManager.onMainEntranceTeleportSpawnedFunction);
|
||||||
}
|
}
|
||||||
|
@ -56,9 +65,10 @@ namespace DunGenPlus {
|
||||||
|
|
||||||
var generator = roundManager.dungeonGenerator.Generator;
|
var generator = roundManager.dungeonGenerator.Generator;
|
||||||
var flow = generator.DungeonFlow;
|
var flow = generator.DungeonFlow;
|
||||||
if (DunGenExtenders.TryGetValue(flow, out var value)) {
|
var extender = API.GetDunGenExtender(flow);
|
||||||
|
if (extender && extender.Active) {
|
||||||
Plugin.logger.LogInfo($"Loading DunGenExtender for {flow.name}");
|
Plugin.logger.LogInfo($"Loading DunGenExtender for {flow.name}");
|
||||||
DunGenPlusGenerator.Activate(generator, value);
|
DunGenPlusGenerator.Activate(generator, extender);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue