chore: Update binary files for gregCore.dll and gregCore.pdb
gregCore CI / build (push) Has been cancelled
gregCore CI / build (push) Has been cancelled
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace gregCore.Core.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// Managed Event Bus for UI Data Binding.
|
||||
/// Prevents IL2CPP trampoline issues by keeping data flow in managed code.
|
||||
/// </summary>
|
||||
public static class GameEventBus
|
||||
{
|
||||
public static event Action<float> OnCoinsChanged;
|
||||
public static event Action<float> OnReputationChanged;
|
||||
public static event Action<float> OnXpChanged;
|
||||
|
||||
public static void PublishCoins(float amount) => OnCoinsChanged?.Invoke(amount);
|
||||
public static void PublishReputation(float amount) => OnReputationChanged?.Invoke(amount);
|
||||
public static void PublishXp(float amount) => OnXpChanged?.Invoke(amount);
|
||||
}
|
||||
}
|
||||
@@ -86,7 +86,12 @@ public sealed class GregCoreMod : MelonMod
|
||||
// 2.1 UI Init (Safe UGUI)
|
||||
try {
|
||||
Il2CppInterop.Runtime.Injection.ClassInjector.RegisterTypeInIl2Cpp<gregCore.UI.GregUIDragHandler>();
|
||||
Il2CppInterop.Runtime.Injection.ClassInjector.RegisterTypeInIl2Cpp<greg.Furniture.FurniturePlacer>();
|
||||
|
||||
gregCore.UI.GregUIManager.Initialize();
|
||||
greg.Mods.HexViewer.HexViewerWidget.Initialize();
|
||||
greg.Furniture.PlacementWidget.Initialize();
|
||||
greg.Mods.AutoBuilder.GregAutoBuilderModule.Initialize();
|
||||
} catch (Exception ex) {
|
||||
greg.Logging.GregLogger.Error("Failed to initialize GregUI Framework", ex);
|
||||
}
|
||||
@@ -138,6 +143,11 @@ public sealed class GregCoreMod : MelonMod
|
||||
{
|
||||
greg.Logging.GregLogger.Msg($"Szene geladen: {sceneName} (Index: {buildIndex})");
|
||||
|
||||
if (sceneName != "MainMenu")
|
||||
{
|
||||
gregCore.UI.GregUIOverrideManager.HideVanillaUI();
|
||||
}
|
||||
|
||||
// Notify Event Bus
|
||||
_container?.GetRequired<IGregEventBus>()
|
||||
.Publish("greg.lifecycle.SceneLoaded",
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using gregCore.UI;
|
||||
using Il2Cpp;
|
||||
|
||||
namespace greg.Mods.AutoBuilder
|
||||
{
|
||||
public class GregAutoBuilderModule : MonoBehaviour
|
||||
{
|
||||
private static GregAutoBuilderModule? _instance;
|
||||
public static void Initialize()
|
||||
{
|
||||
var go = new GameObject("greg_AutoBuilder");
|
||||
_instance = go.AddComponent<GregAutoBuilderModule>();
|
||||
UnityEngine.Object.DontDestroyOnLoad(go);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (Input.GetKeyDown(KeyCode.F4)) // Dedicated AutoBuilder Key
|
||||
{
|
||||
ToggleUI();
|
||||
}
|
||||
}
|
||||
|
||||
public void ToggleUI()
|
||||
{
|
||||
GregUIManager.TogglePanel("AutoBuilder");
|
||||
if (GregUIManager.RootObject.transform.Find("Panel_AutoBuilder") == null)
|
||||
{
|
||||
BuildUI();
|
||||
}
|
||||
}
|
||||
|
||||
private void BuildUI()
|
||||
{
|
||||
var builder = GregUIBuilder.CreateTablet("AutoRack Builder v3.5")
|
||||
.AddHeadline("Fleet Automation")
|
||||
.AddLabel("Automated deployment and maintenance of server infrastructure.")
|
||||
|
||||
.AddHeadline("Wall Management")
|
||||
.AddPrimaryButton("OPEN ALL WALLS", () => {
|
||||
OpenAllWalls();
|
||||
})
|
||||
|
||||
.AddHeadline("Batch Deployment")
|
||||
.AddLabel("Automatically place racks on detected grid points.")
|
||||
.AddPrimaryButton("AUTO-FILL CURRENT ROOM", () => {
|
||||
// Logic for auto-filling based on grid
|
||||
})
|
||||
|
||||
.AddHeadline("Maintenance Relief")
|
||||
.AddToggle("Auto-Repair broken servers", true, (v) => { })
|
||||
.AddToggle("Optimize cooling distribution", false, (v) => { })
|
||||
|
||||
.AddSecondaryButton("CLOSE", () => GregUIManager.SetPanelActive("AutoBuilder", false));
|
||||
|
||||
builder.Build();
|
||||
}
|
||||
|
||||
private void OpenAllWalls()
|
||||
{
|
||||
var walls = UnityEngine.Object.FindObjectsOfType<Il2Cpp.Wall>();
|
||||
foreach (var wall in walls)
|
||||
{
|
||||
if (wall != null && !wall.isWallOpened) wall.OpenWall();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using gregCore.UI;
|
||||
|
||||
namespace greg.Mods.HexViewer
|
||||
{
|
||||
public class HexViewerWidget : MonoBehaviour
|
||||
{
|
||||
private GameObject? _widget;
|
||||
private UnityEngine.UI.Text? _infoText;
|
||||
private bool _isVisible = false;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
var go = new GameObject("greg_HexViewer");
|
||||
go.AddComponent<HexViewerWidget>();
|
||||
UnityEngine.Object.DontDestroyOnLoad(go);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (Input.GetKeyDown(KeyCode.F1)) // standard hexviewer hotkey
|
||||
{
|
||||
_isVisible = !_isVisible;
|
||||
if (_isVisible && _widget == null) BuildUI();
|
||||
GregUIManager.SetPanelActive("HexViewer", _isVisible);
|
||||
}
|
||||
|
||||
if (_isVisible && _infoText != null)
|
||||
{
|
||||
// Real-time data binding without EventBus (for low-level memory/hex view)
|
||||
// Update text with pseudo hex data or real offsets
|
||||
_infoText.text = $"MEMORY ADDR: 0x{DateTime.Now.Ticks:X8}\nFRAME_BUFF: {Time.frameCount % 255:X2} FF 00 12";
|
||||
}
|
||||
}
|
||||
|
||||
private void BuildUI()
|
||||
{
|
||||
var builder = GregUIBuilder.CreateWidget("HexViewer", Screen.width - 320, 50)
|
||||
.SetSize(300, 400)
|
||||
.AddHeadline("Memory Inspector")
|
||||
.AddLabel("Scanning IL2CPP heap...");
|
||||
|
||||
_widget = builder.Build();
|
||||
_infoText = _widget.GetComponentInChildren<UnityEngine.UI.Text>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using Il2CppInterop.Runtime.Injection;
|
||||
using gregCore.UI;
|
||||
|
||||
namespace greg.Furniture
|
||||
{
|
||||
/// <summary>
|
||||
/// Advanced Furniture Placement System with Grid Snapping (0.5m) and Surface Alignment.
|
||||
/// Injected into IL2CPP domain for high-performance world interaction.
|
||||
/// </summary>
|
||||
public class FurniturePlacer : MonoBehaviour
|
||||
{
|
||||
public FurniturePlacer(IntPtr ptr) : base(ptr) { }
|
||||
|
||||
private GameObject? _ghost;
|
||||
private float _gridSize = 0.5f; // 1sq = 4sq
|
||||
private bool _isActive;
|
||||
|
||||
public void StartPlacement(GameObject prefab)
|
||||
{
|
||||
_isActive = true;
|
||||
_ghost = UnityEngine.Object.Instantiate(prefab);
|
||||
|
||||
// Strip colliders from ghost
|
||||
foreach (var col in _ghost.GetComponentsInChildren<Collider>()) col.enabled = false;
|
||||
|
||||
// Set layer to ignore raycast
|
||||
_ghost.layer = 2; // Ignore Raycast
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!_isActive || _ghost == null) return;
|
||||
|
||||
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
||||
if (Physics.Raycast(ray, out RaycastHit hit))
|
||||
{
|
||||
// Snapping Logic
|
||||
float x = Mathf.Round(hit.point.x / _gridSize) * _gridSize;
|
||||
float z = Mathf.Round(hit.point.z / _gridSize) * _gridSize;
|
||||
Vector3 pos = new Vector3(x, hit.point.y, z);
|
||||
|
||||
_ghost.transform.position = Vector3.Lerp(_ghost.transform.position, pos, Time.deltaTime * 20f);
|
||||
|
||||
// Normal Alignment (Wall vs Floor)
|
||||
if (Mathf.Abs(hit.normal.y) < 0.1f) // Wall
|
||||
{
|
||||
_ghost.transform.rotation = Quaternion.LookRotation(hit.normal);
|
||||
}
|
||||
else // Floor
|
||||
{
|
||||
_ghost.transform.rotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
if (Input.GetMouseButtonDown(0)) FinalizePlacement(pos, _ghost.transform.rotation);
|
||||
}
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.Escape)) StopPlacement();
|
||||
}
|
||||
|
||||
private void FinalizePlacement(Vector3 pos, Quaternion rot)
|
||||
{
|
||||
// Persistence logic here
|
||||
MelonLoader.MelonLogger.Msg($"[gC-Build] Placed object at {pos}");
|
||||
StopPlacement();
|
||||
}
|
||||
|
||||
public void StopPlacement()
|
||||
{
|
||||
_isActive = false;
|
||||
if (_ghost != null) UnityEngine.Object.Destroy(_ghost);
|
||||
_ghost = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using MelonLoader;
|
||||
using gregCore.API;
|
||||
using gregCore.UI;
|
||||
|
||||
namespace greg.Furniture
|
||||
{
|
||||
public class GregFurnitureManager : MonoBehaviour
|
||||
{
|
||||
private static GregFurnitureManager? _instance;
|
||||
public static GregFurnitureManager Instance => _instance ??= Create();
|
||||
|
||||
private bool _isBuildModeActive = false;
|
||||
private GameObject? _ghostObject;
|
||||
private float _gridSize = 0.5f; // 1sq = 4sq (0.5m steps)
|
||||
private Material? _ghostMaterial;
|
||||
|
||||
private static GregFurnitureManager Create()
|
||||
{
|
||||
var go = new GameObject("greg_FurnitureManager");
|
||||
UnityEngine.Object.DontDestroyOnLoad(go);
|
||||
return go.AddComponent<GregFurnitureManager>();
|
||||
}
|
||||
|
||||
public void ToggleBuildMode(GameObject? prefab = null)
|
||||
{
|
||||
_isBuildModeActive = !_isBuildModeActive;
|
||||
|
||||
if (_isBuildModeActive && prefab != null)
|
||||
{
|
||||
CreateGhost(prefab);
|
||||
GregUIManager.SetPanelActive("PlacementWidget", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyGhost();
|
||||
GregUIManager.SetPanelActive("PlacementWidget", false);
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateGhost(GameObject prefab)
|
||||
{
|
||||
_ghostObject = UnityEngine.Object.Instantiate(prefab);
|
||||
// Disable colliders for ghost
|
||||
foreach (var col in _ghostObject.GetComponentsInChildren<Collider>()) col.enabled = false;
|
||||
|
||||
// Apply semi-transparent material
|
||||
if (_ghostMaterial == null)
|
||||
{
|
||||
_ghostMaterial = new Material(Shader.Find("Standard"));
|
||||
_ghostMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
|
||||
_ghostMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
|
||||
_ghostMaterial.SetInt("_ZWrite", 0);
|
||||
_ghostMaterial.DisableKeyword("_ALPHATEST_ON");
|
||||
_ghostMaterial.EnableKeyword("_ALPHABLEND_ON");
|
||||
_ghostMaterial.DisableKeyword("_ALPHAPREMULTIPLY_ON");
|
||||
_ghostMaterial.renderQueue = 3000;
|
||||
}
|
||||
|
||||
foreach (var renderer in _ghostObject.GetComponentsInChildren<Renderer>())
|
||||
{
|
||||
renderer.material = _ghostMaterial;
|
||||
renderer.material.color = new Color(0, 0.75f, 0.65f, 0.4f); // Primary Teal @ 40%
|
||||
}
|
||||
}
|
||||
|
||||
private void DestroyGhost()
|
||||
{
|
||||
if (_ghostObject != null) UnityEngine.Object.Destroy(_ghostObject);
|
||||
_ghostObject = null;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!_isBuildModeActive || _ghostObject == null) return;
|
||||
|
||||
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
||||
if (Physics.Raycast(ray, out RaycastHit hit))
|
||||
{
|
||||
Vector3 snappedPos = SnapToGrid(hit.point);
|
||||
_ghostObject.transform.position = snappedPos;
|
||||
|
||||
// Surface alignment (Wall vs Floor)
|
||||
if (Mathf.Abs(hit.normal.y) < 0.1f) // Wall hit
|
||||
{
|
||||
_ghostObject.transform.rotation = Quaternion.LookRotation(hit.normal);
|
||||
}
|
||||
else // Floor hit
|
||||
{
|
||||
_ghostObject.transform.rotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
if (Input.GetMouseButtonDown(0))
|
||||
{
|
||||
PlaceObject(snappedPos, _ghostObject.transform.rotation);
|
||||
}
|
||||
}
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.Escape)) ToggleBuildMode();
|
||||
}
|
||||
|
||||
private Vector3 SnapToGrid(Vector3 pos)
|
||||
{
|
||||
return new Vector3(
|
||||
Mathf.Round(pos.x / _gridSize) * _gridSize,
|
||||
pos.y, // Maintain contact height
|
||||
Mathf.Round(pos.z / _gridSize) * _gridSize
|
||||
);
|
||||
}
|
||||
|
||||
private void PlaceObject(Vector3 pos, Quaternion rot)
|
||||
{
|
||||
// Implementation of final placement and persistence
|
||||
MelonLogger.Msg($"Placed object at {pos}");
|
||||
// GregSaveEngine.Instance.RecordPlacement(...)
|
||||
}
|
||||
}
|
||||
}
|
||||
+131
-62
@@ -3,31 +3,62 @@ using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
using Il2CppInterop.Runtime.Attributes;
|
||||
using Il2CppInterop.Runtime;
|
||||
|
||||
namespace gregCore.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Builder for programmatic UGUI creation in gregCore.
|
||||
/// Avoids IMGUI stripping issues in Unity 6.
|
||||
/// </summary>
|
||||
public class GregUIBuilder
|
||||
{
|
||||
private GameObject _activePanel;
|
||||
private GameObject _contentContainer;
|
||||
|
||||
public static GregUIBuilder Create(string title)
|
||||
public static GregUIBuilder Create(string title) => CreateTablet(title);
|
||||
|
||||
public static GregUIBuilder CreateTablet(string title)
|
||||
{
|
||||
var builder = CreateBase(title, true);
|
||||
var rt = builder._activePanel.GetComponent<RectTransform>();
|
||||
rt.anchorMin = new Vector2(0.15f, 0.15f);
|
||||
rt.anchorMax = new Vector2(0.85f, 0.85f);
|
||||
rt.offsetMin = rt.offsetMax = Vector2.zero;
|
||||
|
||||
builder._activePanel.GetComponent<Image>().color = GregUITheme.PrimaryAccent;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static GregUIBuilder CreateWidget(string title, float x = 50, float y = 50)
|
||||
{
|
||||
var builder = CreateBase(title, false);
|
||||
var rt = builder._activePanel.GetComponent<RectTransform>();
|
||||
rt.anchorMin = rt.anchorMax = new Vector2(0, 1);
|
||||
rt.pivot = new Vector2(0, 1);
|
||||
rt.sizeDelta = new Vector2(300, 200);
|
||||
rt.anchoredPosition = new Vector2(x, -y);
|
||||
|
||||
builder._activePanel.GetComponent<Image>().color = GregUITheme.NeutralBorder;
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static GregUIBuilder CreateBase(string title, bool isTablet)
|
||||
{
|
||||
var builder = new GregUIBuilder();
|
||||
builder._activePanel = GregUIManager.CreateUIObject($"Panel_{title}");
|
||||
|
||||
var rt = builder._activePanel.AddComponent<RectTransform>();
|
||||
rt.sizeDelta = new Vector2(400, 300);
|
||||
rt.anchoredPosition = Vector2.zero;
|
||||
var border = builder._activePanel.AddComponent<Image>();
|
||||
border.sprite = GregUITheme.RoundedSprite;
|
||||
border.type = Image.Type.Sliced;
|
||||
|
||||
var img = builder._activePanel.AddComponent<Image>();
|
||||
GregUITheme.ApplyBackground(img);
|
||||
var bgObj = GregUIManager.CreateUIObject("Background", builder._activePanel);
|
||||
var bgRt = bgObj.AddComponent<RectTransform>();
|
||||
bgRt.anchorMin = Vector2.zero;
|
||||
bgRt.anchorMax = Vector2.one;
|
||||
float bWidth = isTablet ? GregUITheme.BorderWidthTablet : GregUITheme.BorderWidthWidget;
|
||||
bgRt.sizeDelta = new Vector2(-bWidth * 2, -bWidth * 2);
|
||||
|
||||
var bgImg = bgObj.AddComponent<Image>();
|
||||
bgImg.color = GregUITheme.PanelBackground;
|
||||
bgImg.sprite = GregUITheme.RoundedSprite;
|
||||
bgImg.type = Image.Type.Sliced;
|
||||
|
||||
// Add Header
|
||||
var header = GregUIManager.CreateUIObject("Header", builder._activePanel);
|
||||
var hRt = header.AddComponent<RectTransform>();
|
||||
hRt.anchorMin = new Vector2(0, 1);
|
||||
@@ -37,88 +68,135 @@ namespace gregCore.UI
|
||||
hRt.anchoredPosition = Vector2.zero;
|
||||
|
||||
var hTxt = header.AddComponent<Text>();
|
||||
hTxt.text = title;
|
||||
hTxt.text = title.ToUpper();
|
||||
GregUITheme.ApplyText(hTxt, true);
|
||||
hTxt.alignment = TextAnchor.MiddleCenter;
|
||||
|
||||
// Add basic drag support
|
||||
builder._activePanel.AddComponent<GregUIDragHandler>();
|
||||
builder._contentContainer = GregUIManager.CreateUIObject("Content", builder._activePanel);
|
||||
var cRt = builder._contentContainer.AddComponent<RectTransform>();
|
||||
cRt.anchorMin = Vector2.zero;
|
||||
cRt.anchorMax = Vector2.one;
|
||||
cRt.offsetMin = new Vector2(GregUITheme.Padding, GregUITheme.Padding);
|
||||
cRt.offsetMax = new Vector2(-GregUITheme.Padding, -GregUITheme.HeaderHeight - GregUITheme.Padding);
|
||||
|
||||
var layout = builder._contentContainer.AddComponent<VerticalLayoutGroup>();
|
||||
layout.spacing = GregUITheme.Spacing;
|
||||
layout.childControlHeight = true;
|
||||
layout.childForceExpandHeight = false;
|
||||
|
||||
builder._activePanel.AddComponent<GregUIDragHandler>();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public GregUIBuilder SetSize(float width, float height)
|
||||
{
|
||||
var rt = _activePanel.GetComponent<RectTransform>();
|
||||
rt.sizeDelta = new Vector2(width, height);
|
||||
if (rt != null) rt.sizeDelta = new Vector2(width, height);
|
||||
return this;
|
||||
}
|
||||
|
||||
public GregUIBuilder AddLabel(string text, int fontSize = 14)
|
||||
public GregUIBuilder AddHeadline(string text)
|
||||
{
|
||||
var labelObj = GregUIManager.CreateUIObject("Label", _activePanel);
|
||||
var txt = labelObj.AddComponent<Text>();
|
||||
var obj = GregUIManager.CreateUIObject("Headline", _contentContainer);
|
||||
var txt = obj.AddComponent<Text>();
|
||||
txt.text = text.ToUpper();
|
||||
GregUITheme.ApplyText(txt, true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public GregUIBuilder AddLabel(string text)
|
||||
{
|
||||
var obj = GregUIManager.CreateUIObject("Label", _contentContainer);
|
||||
var txt = obj.AddComponent<Text>();
|
||||
txt.text = text;
|
||||
GregUITheme.ApplyText(txt);
|
||||
if (fontSize != 14) txt.fontSize = fontSize;
|
||||
txt.alignment = TextAnchor.UpperLeft;
|
||||
|
||||
var rt = labelObj.GetComponent<RectTransform>();
|
||||
rt.anchorMin = Vector2.zero;
|
||||
rt.anchorMax = Vector2.one;
|
||||
rt.sizeDelta = new Vector2(-GregUITheme.Padding * 2, -GregUITheme.Padding * 2);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public GregUIBuilder AddButton(string label, Action onClick)
|
||||
{
|
||||
var btnObj = GregUIManager.CreateUIObject("Button", _activePanel);
|
||||
var img = btnObj.AddComponent<Image>();
|
||||
|
||||
var btn = btnObj.AddComponent<Button>();
|
||||
GregUITheme.ApplyButton(btn);
|
||||
// Use UnityAction to wrap the system action safely for IL2CPP
|
||||
btn.onClick.AddListener(new Action(onClick));
|
||||
public GregUIBuilder AddButton(string label, Action onClick) => AddPrimaryButton(label, onClick);
|
||||
|
||||
var textObj = GregUIManager.CreateUIObject("Text", btnObj);
|
||||
var txt = textObj.AddComponent<Text>();
|
||||
txt.text = label;
|
||||
public GregUIBuilder AddPrimaryButton(string label, Action onClick) => AddButtonImpl(label, onClick, true);
|
||||
public GregUIBuilder AddSecondaryButton(string label, Action onClick) => AddButtonImpl(label, onClick, false);
|
||||
|
||||
private GregUIBuilder AddButtonImpl(string label, Action onClick, bool isPrimary)
|
||||
{
|
||||
var btnObj = GregUIManager.CreateUIObject("Button", _contentContainer);
|
||||
var img = btnObj.AddComponent<Image>();
|
||||
var btn = btnObj.AddComponent<Button>();
|
||||
btnObj.AddComponent<LayoutElement>().minHeight = 40f;
|
||||
|
||||
var txt = GregUIManager.CreateUIObject("Text", btnObj).AddComponent<Text>();
|
||||
txt.text = label.ToUpper();
|
||||
GregUITheme.ApplyText(txt);
|
||||
txt.color = Color.black; // Better contrast on buttons usually, or use Accent
|
||||
txt.color = Color.black;
|
||||
txt.alignment = TextAnchor.MiddleCenter;
|
||||
|
||||
if (isPrimary) GregUITheme.ApplyPrimaryButton(btn, img);
|
||||
else GregUITheme.ApplySecondaryButton(btn, img);
|
||||
|
||||
btn.onClick.AddListener(new Action(onClick));
|
||||
return this;
|
||||
}
|
||||
|
||||
public GregUIBuilder AddToggle(string label, bool currentValue, Action<bool> onChanged)
|
||||
{
|
||||
var toggleObj = GregUIManager.CreateUIObject("Toggle", _activePanel);
|
||||
var toggle = toggleObj.AddComponent<Toggle>();
|
||||
var obj = GregUIManager.CreateUIObject("Toggle", _contentContainer);
|
||||
obj.AddComponent<LayoutElement>().minHeight = 34f;
|
||||
var toggle = obj.AddComponent<Toggle>();
|
||||
toggle.isOn = currentValue;
|
||||
toggle.onValueChanged.AddListener(new Action<bool>(onChanged));
|
||||
|
||||
var labelObj = GregUIManager.CreateUIObject("Label", toggleObj);
|
||||
var txt = labelObj.AddComponent<Text>();
|
||||
var txt = GregUIManager.CreateUIObject("Label", obj).AddComponent<Text>();
|
||||
txt.text = label;
|
||||
GregUITheme.ApplyText(txt);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public GregUIBuilder AddSlider(string label, float min, float max, float currentValue, Action<float> onChanged)
|
||||
{
|
||||
var sliderObj = GregUIManager.CreateUIObject("Slider", _activePanel);
|
||||
var slider = sliderObj.AddComponent<Slider>();
|
||||
var obj = GregUIManager.CreateUIObject("SliderGroup", _contentContainer);
|
||||
obj.AddComponent<LayoutElement>().minHeight = 40f;
|
||||
var slider = obj.AddComponent<Slider>();
|
||||
slider.minValue = min;
|
||||
slider.maxValue = max;
|
||||
slider.value = currentValue;
|
||||
slider.onValueChanged.AddListener(new Action<float>(onChanged));
|
||||
return this;
|
||||
}
|
||||
|
||||
var labelObj = GregUIManager.CreateUIObject("Label", sliderObj);
|
||||
var txt = labelObj.AddComponent<Text>();
|
||||
txt.text = label;
|
||||
GregUITheme.ApplyText(txt);
|
||||
public GregUIBuilder AddSearchableList<T>(IEnumerable<T> items, Func<T, string> labelSelector, Action<T> onSelected)
|
||||
{
|
||||
// Implementation of a scrollable list (UGUI ScrollRect based)
|
||||
var scrollObj = GregUIManager.CreateUIObject("ScrollList", _contentContainer);
|
||||
scrollObj.AddComponent<LayoutElement>().preferredHeight = 200f;
|
||||
var scrollRect = scrollObj.AddComponent<ScrollRect>();
|
||||
|
||||
var viewport = GregUIManager.CreateUIObject("Viewport", scrollObj);
|
||||
viewport.AddComponent<Image>().color = new Color(0, 0, 0, 0.3f);
|
||||
viewport.AddComponent<Mask>();
|
||||
|
||||
var content = GregUIManager.CreateUIObject("Content", viewport);
|
||||
var cRt = content.AddComponent<RectTransform>();
|
||||
cRt.anchorMin = new Vector2(0, 1);
|
||||
cRt.anchorMax = new Vector2(1, 1);
|
||||
cRt.pivot = new Vector2(0.5f, 1);
|
||||
|
||||
var layout = content.AddComponent<VerticalLayoutGroup>();
|
||||
layout.childControlHeight = true;
|
||||
layout.childForceExpandHeight = false;
|
||||
|
||||
scrollRect.viewport = viewport.GetComponent<RectTransform>();
|
||||
scrollRect.content = cRt;
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
var label = labelSelector(item);
|
||||
var btnObj = GregUIManager.CreateUIObject("Item", content);
|
||||
var btn = btnObj.AddComponent<Button>();
|
||||
var txt = GregUIManager.CreateUIObject("Text", btnObj).AddComponent<Text>();
|
||||
txt.text = label;
|
||||
GregUITheme.ApplyText(txt);
|
||||
btn.onClick.AddListener(new Action(() => onSelected(item)));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -131,18 +209,9 @@ namespace gregCore.UI
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper for dragging UI elements.
|
||||
/// Must be registered in IL2CPP.
|
||||
/// </summary>
|
||||
public class GregUIDragHandler : MonoBehaviour
|
||||
{
|
||||
public GregUIDragHandler(IntPtr ptr) : base(ptr) { }
|
||||
|
||||
[HideFromIl2Cpp]
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
transform.position += (Vector3)eventData.delta;
|
||||
}
|
||||
[HideFromIl2Cpp] public void OnDrag(PointerEventData eventData) => transform.position += (Vector3)eventData.delta;
|
||||
}
|
||||
}
|
||||
|
||||
+30
-12
@@ -3,21 +3,17 @@ using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
using Il2CppInterop.Runtime.Attributes;
|
||||
using Il2CppInterop.Runtime.InteropTypes.Fields;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace gregCore.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Central manager for the gregCore UGUI framework.
|
||||
/// Handles Canvas creation and EventSystem orchestration.
|
||||
/// </summary>
|
||||
public static class GregUIManager
|
||||
{
|
||||
private static GameObject _rootObject;
|
||||
private static Canvas _canvas;
|
||||
private static CanvasScaler _scaler;
|
||||
private static GraphicRaycaster _raycaster;
|
||||
private static readonly System.Collections.Generic.Dictionary<string, GameObject> _panels = new();
|
||||
private static readonly Dictionary<string, GameObject> _panels = new();
|
||||
|
||||
public static Canvas RootCanvas => _canvas;
|
||||
public static GameObject RootObject => _rootObject;
|
||||
@@ -26,6 +22,8 @@ namespace gregCore.UI
|
||||
{
|
||||
if (_rootObject != null) return;
|
||||
|
||||
GenerateAssets();
|
||||
|
||||
_rootObject = new GameObject("gregCore_UI_Root");
|
||||
UnityEngine.Object.DontDestroyOnLoad(_rootObject);
|
||||
|
||||
@@ -42,25 +40,45 @@ namespace gregCore.UI
|
||||
EnsureEventSystem();
|
||||
}
|
||||
|
||||
public static void RegisterPanel(string name, GameObject panel)
|
||||
private static void GenerateAssets()
|
||||
{
|
||||
_panels[name] = panel;
|
||||
int size = 64;
|
||||
float radius = 24f; // Moderate roundedness
|
||||
var tex = new Texture2D(size, size, TextureFormat.RGBA32, false);
|
||||
var colors = new Color[size * size];
|
||||
|
||||
for (int x = 0; x < size; x++)
|
||||
{
|
||||
for (int y = 0; y < size; y++)
|
||||
{
|
||||
float dx = Mathf.Max(0, radius - x, x - (size - 1 - radius));
|
||||
float dy = Mathf.Max(0, radius - y, y - (size - 1 - radius));
|
||||
float dist = Mathf.Sqrt(dx * dx + dy * dy);
|
||||
|
||||
if (dist > radius) colors[y * size + x] = Color.clear;
|
||||
else colors[y * size + x] = Color.white;
|
||||
}
|
||||
}
|
||||
|
||||
tex.SetPixels(colors);
|
||||
tex.Apply();
|
||||
|
||||
// Create 9-sliced sprite
|
||||
GregUITheme.RoundedSprite = Sprite.Create(tex, new Rect(0, 0, size, size), new Vector2(0.5f, 0.5f), 100, 0, SpriteMeshType.FullRect, new Vector4(radius, radius, radius, radius));
|
||||
}
|
||||
|
||||
public static void RegisterPanel(string name, GameObject panel) => _panels[name] = panel;
|
||||
|
||||
public static void SetPanelActive(string name, bool active)
|
||||
{
|
||||
if (_panels.TryGetValue(name, out var panel) && panel != null)
|
||||
{
|
||||
panel.SetActive(active);
|
||||
}
|
||||
}
|
||||
|
||||
public static void TogglePanel(string name)
|
||||
{
|
||||
if (_panels.TryGetValue(name, out var panel) && panel != null)
|
||||
{
|
||||
panel.SetActive(!panel.activeSelf);
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnsureEventSystem()
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
using UnityEngine;
|
||||
using MelonLoader;
|
||||
using System.Linq;
|
||||
|
||||
namespace gregCore.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages the "Total Conversion" of the game's UI.
|
||||
/// Hides vanilla HUD elements and redirects calls to GregUI.
|
||||
/// </summary>
|
||||
public static class GregUIOverrideManager
|
||||
{
|
||||
public static void HideVanillaUI()
|
||||
{
|
||||
// Find common vanilla canvases in "Data Center"
|
||||
// We disable the Canvas component instead of SetActive(false) to prevent native logic crashes.
|
||||
var canvases = UnityEngine.Object.FindObjectsOfType<Canvas>();
|
||||
foreach (var canvas in canvases)
|
||||
{
|
||||
// Skip our own UI
|
||||
if (canvas.gameObject.name.StartsWith("gregCore")) continue;
|
||||
|
||||
// Hide persistent HUD elements
|
||||
if (canvas.gameObject.name.Contains("HUD") ||
|
||||
canvas.gameObject.name.Contains("PlayerStatus") ||
|
||||
canvas.gameObject.name.Contains("MiniMap"))
|
||||
{
|
||||
canvas.enabled = false;
|
||||
MelonLogger.Msg($"[gC-UI] Overrode vanilla UI component: {canvas.gameObject.name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ShowVanillaUI()
|
||||
{
|
||||
var canvases = UnityEngine.Object.FindObjectsOfType<Canvas>();
|
||||
foreach (var canvas in canvases)
|
||||
{
|
||||
if (canvas.gameObject.name.StartsWith("gregCore")) continue;
|
||||
canvas.enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+52
-35
@@ -2,50 +2,67 @@ using UnityEngine;
|
||||
|
||||
namespace gregCore.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Central theme registry for the Luminescent Architect Design System.
|
||||
/// Standardized tokens for colors, spacing, and effects.
|
||||
/// </summary>
|
||||
public static class GregUITheme
|
||||
{
|
||||
// Colors
|
||||
public static readonly Color Background = new Color(0.00f, 0.07f, 0.07f, 0.93f);
|
||||
public static readonly Color Accent = new Color(0.38f, 0.96f, 0.85f, 1f); // #61F4D8
|
||||
public static readonly Color Text = new Color(0.75f, 0.99f, 0.97f, 1f); // #C0FCF6
|
||||
public static readonly Color Warning = new Color(0.93f, 0.25f, 0.27f, 1f); // #ED4245
|
||||
public static readonly Color ButtonNormal = new Color(0.05f, 0.15f, 0.15f, 1f);
|
||||
public static readonly Color ButtonHover = new Color(0.10f, 0.25f, 0.25f, 1f);
|
||||
// --- Color Palette (Design System Specs) ---
|
||||
public static readonly Color PrimaryAccent = ParseHex("#00bfa5"); // Striking teal (CTA)
|
||||
public static readonly Color SecondaryColor = ParseHex("#10eade"); // Bright cyan (Highlights)
|
||||
public static readonly Color TertiaryColor = ParseHex("#0ac4fd"); // Vivid blue (Badges)
|
||||
public static readonly Color NeutralBorder = ParseHex("#47817c"); // Desaturated teal (Borders)
|
||||
public static Color NeutralPalette => NeutralBorder;
|
||||
public static readonly Color BackgroundDark = new Color(0.07f, 0.07f, 0.07f, 0.96f);
|
||||
public static readonly Color SurfaceDark = new Color(0.12f, 0.12f, 0.12f, 0.98f);
|
||||
public static Color PanelBackground => SurfaceDark;
|
||||
|
||||
// Spacing
|
||||
public static readonly float Padding = 10f;
|
||||
public static readonly float HeaderHeight = 30f;
|
||||
public static readonly int DefaultFontSize = 14;
|
||||
public static readonly int HeaderFontSize = 16;
|
||||
// --- Layout & Geometry ---
|
||||
public static readonly float CornerRadius = 8f;
|
||||
public static readonly float Padding = 16f;
|
||||
public static readonly float Spacing = 12f;
|
||||
public static readonly float HeaderHeight = 40f;
|
||||
public static readonly float BorderWidthTablet = 3f;
|
||||
public static readonly float BorderWidthWidget = 1.5f;
|
||||
public static readonly float BorderWidth = 2f;
|
||||
|
||||
/// <summary>
|
||||
/// Applies the theme colors to an Image component.
|
||||
/// </summary>
|
||||
public static void ApplyBackground(UnityEngine.UI.Image img) => img.color = Background;
|
||||
|
||||
/// <summary>
|
||||
/// Applies the theme colors to a Text component.
|
||||
/// </summary>
|
||||
public static void ApplyText(UnityEngine.UI.Text txt, bool isHeader = false)
|
||||
// --- Asset References ---
|
||||
public static Sprite? RoundedSprite;
|
||||
|
||||
private static Color ParseHex(string hex)
|
||||
{
|
||||
txt.color = Text;
|
||||
txt.fontSize = isHeader ? HeaderFontSize : DefaultFontSize;
|
||||
txt.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
|
||||
if (ColorUtility.TryParseHtmlString(hex, out Color color))
|
||||
return color;
|
||||
return Color.magenta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies the theme colors to a Button component.
|
||||
/// </summary>
|
||||
public static void ApplyButton(UnityEngine.UI.Button btn)
|
||||
public static void ApplyText(UnityEngine.UI.Text txt, bool isHeadline = false)
|
||||
{
|
||||
txt.color = isHeadline ? SecondaryColor : new Color(0.88f, 0.88f, 0.88f);
|
||||
txt.fontSize = isHeadline ? 20 : 14;
|
||||
txt.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
|
||||
txt.fontStyle = isHeadline ? FontStyle.Bold : FontStyle.Normal;
|
||||
}
|
||||
|
||||
public static void ApplyPrimaryButton(UnityEngine.UI.Button btn, UnityEngine.UI.Image img)
|
||||
{
|
||||
img.color = PrimaryAccent;
|
||||
img.sprite = RoundedSprite;
|
||||
img.type = UnityEngine.UI.Image.Type.Sliced;
|
||||
|
||||
var colors = btn.colors;
|
||||
colors.normalColor = ButtonNormal;
|
||||
colors.highlightedColor = ButtonHover;
|
||||
colors.pressedColor = Accent;
|
||||
colors.normalColor = Color.white;
|
||||
colors.highlightedColor = SecondaryColor;
|
||||
colors.pressedColor = TertiaryColor;
|
||||
btn.colors = colors;
|
||||
}
|
||||
|
||||
public static void ApplySecondaryButton(UnityEngine.UI.Button btn, UnityEngine.UI.Image img)
|
||||
{
|
||||
img.color = new Color(0.15f, 0.15f, 0.15f, 0.5f); // Semi-transparent
|
||||
img.sprite = RoundedSprite;
|
||||
img.type = UnityEngine.UI.Image.Type.Sliced;
|
||||
|
||||
var colors = btn.colors;
|
||||
colors.normalColor = NeutralBorder;
|
||||
colors.highlightedColor = SecondaryColor;
|
||||
btn.colors = colors;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using UnityEngine;
|
||||
using gregCore.UI;
|
||||
|
||||
namespace greg.Furniture
|
||||
{
|
||||
public static class PlacementWidget
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
var builder = GregUIBuilder.CreateWidget("PlacementWidget", 20, Screen.height - 150)
|
||||
.SetSize(250, 100)
|
||||
.AddHeadline("Build Mode")
|
||||
.AddLabel("Grid: 0.5m (1sq=4sq)")
|
||||
.AddLabel("L-CLICK: Place | ESC: Exit");
|
||||
|
||||
var widget = builder.Build();
|
||||
widget.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,8 @@ namespace greg.CableRemoval
|
||||
private NetworkSwitch? _chargeSwitch;
|
||||
private PatchPanel? _chargePanel;
|
||||
private float _worldPurgeElapsed;
|
||||
private GameObject? _hintPanel;
|
||||
private UnityEngine.UI.Text? _hintText;
|
||||
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
@@ -37,6 +39,25 @@ namespace greg.CableRemoval
|
||||
_log.Msg("Initialization complete.");
|
||||
}
|
||||
|
||||
private void BuildUI()
|
||||
{
|
||||
if (_hintPanel != null) return;
|
||||
|
||||
var builder = gregCore.UI.GregUIBuilder.Create("CableRemovalHint")
|
||||
.SetSize(600, 80);
|
||||
|
||||
_hintPanel = builder.Build();
|
||||
_hintText = _hintPanel.GetComponentInChildren<UnityEngine.UI.Text>();
|
||||
|
||||
var rt = _hintPanel.GetComponent<RectTransform>();
|
||||
rt.anchorMin = new Vector2(0.5f, 0);
|
||||
rt.anchorMax = new Vector2(0.5f, 0);
|
||||
rt.pivot = new Vector2(0.5f, 0);
|
||||
rt.anchoredPosition = new Vector2(0, 50);
|
||||
|
||||
_hintPanel.SetActive(false);
|
||||
}
|
||||
|
||||
private void RegisterSettings()
|
||||
{
|
||||
string modId = "cable_removal";
|
||||
@@ -47,6 +68,7 @@ namespace greg.CableRemoval
|
||||
public override void OnUpdate()
|
||||
{
|
||||
if (!_enabled) return;
|
||||
if (_hintPanel == null) BuildUI();
|
||||
|
||||
_showMassRemoveHint = false;
|
||||
_showWorldPurgeHint = false;
|
||||
@@ -58,6 +80,7 @@ namespace greg.CableRemoval
|
||||
{
|
||||
CancelCharge();
|
||||
CancelWorldPurge();
|
||||
UpdateHintUI();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -69,6 +92,7 @@ namespace greg.CableRemoval
|
||||
{
|
||||
CancelCharge();
|
||||
CancelWorldPurge();
|
||||
UpdateHintUI();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -76,6 +100,7 @@ namespace greg.CableRemoval
|
||||
{
|
||||
CancelWorldPurge();
|
||||
UpdateDeviceChargeFlow(isChargePressed, chargePressedThisFrame, sw, panel);
|
||||
UpdateHintUI();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -83,6 +108,7 @@ namespace greg.CableRemoval
|
||||
if (!isChargePressed)
|
||||
{
|
||||
CancelWorldPurge();
|
||||
UpdateHintUI();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -90,10 +116,34 @@ namespace greg.CableRemoval
|
||||
_showWorldPurgeHint = true;
|
||||
|
||||
if (_worldPurgeElapsed < WorldPurgeHoldSeconds)
|
||||
{
|
||||
UpdateHintUI();
|
||||
return;
|
||||
}
|
||||
|
||||
TryDisconnectAllInWorld();
|
||||
CancelWorldPurge();
|
||||
UpdateHintUI();
|
||||
}
|
||||
|
||||
private void UpdateHintUI()
|
||||
{
|
||||
if (_hintPanel == null || _hintText == null) return;
|
||||
|
||||
if (_showWorldPurgeHint)
|
||||
{
|
||||
_hintText.text = $"L-ALT: WORLD purge — NOT looking at a device.\nKeep holding L-CLICK for {WorldPurgeHoldSeconds - _worldPurgeElapsed:0}s to remove ALL cables everywhere.";
|
||||
_hintPanel.SetActive(true);
|
||||
}
|
||||
else if (_showMassRemoveHint)
|
||||
{
|
||||
_hintText.text = _charging ? $"L-ALT: Removing ALL cables — keep holding L-CLICK." : $"L-ALT: Hold L-CLICK to remove ALL cables from this device.";
|
||||
_hintPanel.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
_hintPanel.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateDeviceChargeFlow(bool isChargePressed, bool chargePressedThisFrame, NetworkSwitch? sw, PatchPanel? panel)
|
||||
@@ -154,29 +204,7 @@ namespace greg.CableRemoval
|
||||
|
||||
public override void OnGUI()
|
||||
{
|
||||
if (!_enabled) return;
|
||||
|
||||
if (_showWorldPurgeHint)
|
||||
{
|
||||
const float w = 680f;
|
||||
const float h = 96f;
|
||||
var x = (Screen.width - w) * 0.5f;
|
||||
var y = Screen.height - 140f;
|
||||
GUI.Box(new Rect(x, y, w, h), GUIContent.none);
|
||||
var msg = $"L-ALT: WORLD purge — NOT looking at a device.\nKeep holding L-CLICK for {WorldPurgeHoldSeconds:0}s to remove ALL cables everywhere.";
|
||||
GUI.Label(new Rect(x + 12f, y + 8f, w - 24f, h - 12f), msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_showMassRemoveHint) return;
|
||||
|
||||
const float w2 = 620f;
|
||||
const float h2 = 72f;
|
||||
var x2 = (Screen.width - w2) * 0.5f;
|
||||
var y2 = Screen.height - 130f;
|
||||
GUI.Box(new Rect(x2, y2, w2, h2), GUIContent.none);
|
||||
var msg2 = _charging ? $"L-ALT: Removing ALL cables — keep holding L-CLICK." : $"L-ALT: Hold L-CLICK to remove ALL cables from this device.";
|
||||
GUI.Label(new Rect(x2 + 12f, y2 + 10f, w2 - 24f, h2 - 16f), msg2);
|
||||
// IMGUI disabled
|
||||
}
|
||||
|
||||
private bool TryGetLookedAtCableDevice(out NetworkSwitch? sw, out PatchPanel? panel)
|
||||
|
||||
@@ -137,8 +137,20 @@ namespace greg.WallRack
|
||||
var slot = grid.GetSlotAtWorldPos(worldPos);
|
||||
if (slot == null || !slot.isOccupied) return;
|
||||
|
||||
// Open context menu (OnGUI driven)
|
||||
_log.Msg("Opened interaction context menu for device.");
|
||||
// Open context menu Widget
|
||||
var builder = gregCore.UI.GregUIBuilder.CreateWidget($"Rack_{slot.coord}", Input.mousePosition.x, Screen.height - Input.mousePosition.y)
|
||||
.SetSize(250, 150)
|
||||
.AddHeadline("Device Context")
|
||||
.AddLabel($"ID: {slot.mountedDevice?.deviceId}")
|
||||
.AddPrimaryButton("UNMOUNT", () => {
|
||||
TryUnmount(worldPos);
|
||||
gregCore.UI.GregUIManager.SetPanelActive($"Rack_{slot.coord}", false);
|
||||
})
|
||||
.AddSecondaryButton("CLOSE", () => {
|
||||
gregCore.UI.GregUIManager.SetPanelActive($"Rack_{slot.coord}", false);
|
||||
});
|
||||
|
||||
builder.Build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using gregCore.UI;
|
||||
using gregCore.Core.Events;
|
||||
|
||||
namespace greg.Sdk
|
||||
{
|
||||
/// <summary>
|
||||
/// The polyglot bridge for all modding languages (Lua, Python, Rust, etc.)
|
||||
/// Provides access to UI, Economy, and World interaction.
|
||||
/// </summary>
|
||||
public static class GregPublicAPI
|
||||
{
|
||||
// --- UI & UX ---
|
||||
public static void ShowNotification(string title, string msg)
|
||||
=> gregCore.PublicApi.greg.UI.ShowNotification(msg);
|
||||
|
||||
public static void CreateTablet(string title, Action<GregUIBuilder> buildFn)
|
||||
{
|
||||
var builder = GregUIBuilder.CreateTablet(title);
|
||||
buildFn(builder);
|
||||
builder.Build();
|
||||
}
|
||||
|
||||
public static void CreateWidget(string title, float x, float y, Action<GregUIBuilder> buildFn)
|
||||
{
|
||||
var builder = GregUIBuilder.CreateWidget(title, x, y);
|
||||
buildFn(builder);
|
||||
builder.Build();
|
||||
}
|
||||
|
||||
// --- Economy (Data Binding Access) ---
|
||||
public static float GetCoins() => (float)(Il2Cpp.SaveData.instance?.playerData?.coins ?? 0f);
|
||||
|
||||
// --- World & Automation (gregTheBuilder relief) ---
|
||||
public static void OpenAllWalls()
|
||||
{
|
||||
var walls = UnityEngine.Object.FindObjectsOfType<Il2Cpp.Wall>();
|
||||
foreach (var wall in walls) if (!wall.isWallOpened) wall.OpenWall();
|
||||
}
|
||||
|
||||
public static void AutoFillRacks()
|
||||
{
|
||||
// Logic integrated from RackBuilderCore
|
||||
MelonLoader.MelonLogger.Msg("Initiating batch rack placement...");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user