mirror of
https://github.com/soarqin/DSP_Mods.git
synced 2025-12-09 14:53:30 +08:00
UXAssist: Work in progress
This commit is contained in:
85
UXAssist/Common/I18N.cs
Normal file
85
UXAssist/Common/I18N.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using HarmonyLib;
|
||||
|
||||
namespace UXAssist.Common;
|
||||
|
||||
public static class I18N
|
||||
{
|
||||
private static bool _initialized;
|
||||
|
||||
public static Action OnInitialized;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
Harmony.CreateAndPatchAll(typeof(I18N));
|
||||
}
|
||||
|
||||
public static bool Initialized() => _initialized;
|
||||
private static int _nextID = 1;
|
||||
private static readonly List<StringProto> StringsToAdd = new();
|
||||
public static void Add(string key, string enus, string zhcn = null, string frfr = null)
|
||||
{
|
||||
var strings = LDB._strings;
|
||||
var strProto = new StringProto
|
||||
{
|
||||
Name = key,
|
||||
SID = "",
|
||||
ENUS = enus,
|
||||
ZHCN = string.IsNullOrEmpty(zhcn) ? enus : zhcn,
|
||||
FRFR = string.IsNullOrEmpty(frfr) ? enus : frfr
|
||||
};
|
||||
StringsToAdd.Add(strProto);
|
||||
}
|
||||
|
||||
public static void Apply()
|
||||
{
|
||||
if (!_initialized) return;
|
||||
var strings = LDB._strings;
|
||||
var index = strings.dataArray.Length;
|
||||
strings.dataArray = strings.dataArray.Concat(StringsToAdd).ToArray();
|
||||
StringsToAdd.Clear();
|
||||
var newIndex = strings.dataArray.Length;
|
||||
for (; index < newIndex; index++)
|
||||
{
|
||||
var strProto = strings.dataArray[index];
|
||||
strProto.ID = GetNextID();
|
||||
strings.dataIndices[strProto.ID] = index;
|
||||
strings.nameIndices[strings.dataArray[index].Name] = index;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix, HarmonyPriority(Priority.Last), HarmonyPatch(typeof(VFPreload), "InvokeOnLoadWorkEnded")]
|
||||
private static void VFPreload_InvokeOnLoadWorkEnded_Postfix()
|
||||
{
|
||||
if (_initialized) return;
|
||||
_initialized = true;
|
||||
if (StringsToAdd.Count == 0)
|
||||
{
|
||||
OnInitialized?.Invoke();
|
||||
return;
|
||||
}
|
||||
|
||||
Apply();
|
||||
OnInitialized?.Invoke();
|
||||
}
|
||||
|
||||
private static int GetNextID()
|
||||
{
|
||||
var strings = LDB._strings;
|
||||
while (_nextID <= 12000)
|
||||
{
|
||||
if (!strings.dataIndices.ContainsKey(_nextID))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
_nextID++;
|
||||
}
|
||||
|
||||
var result = _nextID;
|
||||
_nextID++;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
200
UXAssist/README.md
Normal file
200
UXAssist/README.md
Normal file
@@ -0,0 +1,200 @@
|
||||
# CheatEnabler
|
||||
|
||||
#### Add various cheat functions while disabling abnormal determinants
|
||||
#### 添加一些作弊功能,同时屏蔽异常检测
|
||||
|
||||
## Changlog
|
||||
* 2.2.7
|
||||
+ New function: `Construct only nodes but frames`
|
||||
+ Opening config panel does not close inventory panel now
|
||||
+ Remove `Input direction conflict` check while using `Remove some build conditions`
|
||||
+ Fix a bug that prevents `Belt signal alt format` from switching number formats for current belt signals
|
||||
* 2.2.6
|
||||
+ New function: `Stop ejectors when available nodes are all filled up`
|
||||
+ Fix a bug that absorb solar sails on unfinised nodes
|
||||
* 2.2.5
|
||||
+ Skip all intermediate states and absorb solar sails instantly while enable `Quick absorb`, `Skip bullet period` and `Skip absorption period` at the same time.
|
||||
+ Fix a problem that `Quick absorb` does not absorb all solar sails instantly when most nodes are full.
|
||||
+ Fix crash while using with some mods
|
||||
* 2.2.4
|
||||
+ New function: `Enable player actions in globe view`
|
||||
+ Fix UI bug
|
||||
* 2.2.3
|
||||
+ New function: `Remove some build conditions`
|
||||
+ Fix compatibility with some mods
|
||||
* 2.2.2
|
||||
+ New function: `Assign game to currrnet account`
|
||||
+ New subfunction: `Belt signal alt format`
|
||||
+ Fix a crash on using `Initialize this Planet`
|
||||
+ Fix belt build in `Finish build immediately`
|
||||
* 2.2.1
|
||||
+ Check condition for miners even when `Build without condition` is enabled.
|
||||
+ Fix a patch issue that may cause `Build without condition` not working.
|
||||
* 2.2.0
|
||||
+ Add some power related functions
|
||||
+ Add a subfunction to belt signal item generation, which simulates production process of raws and intermediates on statistics
|
||||
+ Split some functions from Architect mode
|
||||
* 2.1.0
|
||||
+ Belt signal item generation
|
||||
+ Fix window display priority which may cause tips to be covered by main window
|
||||
* 2.0.0
|
||||
+ Refactorying codes
|
||||
+ UI implementation
|
||||
+ Add a lot of functions
|
||||
* 1.0.0
|
||||
+ Initial release
|
||||
|
||||
## Usage
|
||||
|
||||
* Press `` LAlt+`(BackQuote) `` to call up the config panel. You can change the shortcut on the panel.
|
||||
* There are also buttons on title screen and planet minimap area to call up the config panel.
|
||||
* Features:
|
||||
+ Strict hotkey dectection for build menu, thus building hotkeys(0~9, F1~F10, X, U) are not triggered while holding Ctrl/Alt/Shift.
|
||||
+ General:
|
||||
+ Enable Dev Shortcuts (check config panel for usage)
|
||||
+ Disable Abnormal Checks
|
||||
+ Unlock techs with key-modifiers (Ctrl/Alt/Shift)
|
||||
+ Assign game to currrnet account
|
||||
+ Factory:
|
||||
+ Finish build immediately
|
||||
+ Architect mode (Infinite buildings)
|
||||
+ Unlimited interactive range
|
||||
+ Build without condition
|
||||
+ Remove some build conditions
|
||||
+ No collision
|
||||
+ Sunlight at night
|
||||
+ Belt signal item generation
|
||||
+ Count all raws and intermediates in statistics
|
||||
+ Belt signal alt format
|
||||
+ Remove space limit between wind turbines and solar panels
|
||||
+ Boost power generations for kinds of power generators
|
||||
+ Planet:
|
||||
+ Enable player actions in globe view
|
||||
+ Infinite Natural Resources
|
||||
+ Fast Mining
|
||||
+ Pump Anywhere
|
||||
+ Terraform without enought sands
|
||||
+ Re-intialize planet (without reseting veins)
|
||||
+ Quick dismantle all buildings (without drops)
|
||||
+ Dyson Sphere:
|
||||
+ Stop ejectors when available nodes are all filled up
|
||||
+ Construct only nodes but frames
|
||||
+ Skip bullet period
|
||||
+ Skip absorption period
|
||||
+ Quick absorb
|
||||
+ Eject anyway
|
||||
+ Re-initialize Dyson Spheres
|
||||
+ Quick dismantle Dyson Shells
|
||||
+ Birth star:
|
||||
+ Rare resources on birth planet
|
||||
+ Solid flat on birth planet
|
||||
+ High luminosity for birth star
|
||||
|
||||
## Notes
|
||||
* Please upgrade `BepInEx` 5.4.21 or later if using with [BlueprintTweaks](https://dsp.thunderstore.io/package/kremnev8/BlueprintTweaks/) to avoid possible conflicts.
|
||||
+ You can download `BepInEx` [here](https://github.com/bepinex/bepinex/releases/latest)(choose x64 edition).
|
||||
+ If using with r2modman, you can upgrade `BepInEx` by clicking `Settings` -> `Browse profile folder`, then extract downloaded zip to the folder and overwrite existing files.
|
||||
|
||||
## CREDITS
|
||||
* [Dyson Sphere Program](https://store.steampowered.com/app/1366540): The great game
|
||||
* [BepInEx](https://bepinex.dev/): Base modding framework
|
||||
* [Multifunction_mod](https://github.com/blacksnipebiu/Multifunction_mod): Some cheat functions
|
||||
* [LSTM](https://github.com/hetima/DSP_LSTM) & [PlanetFinder](https://github.com/hetima/DSP_PlanetFinder): UI implementations
|
||||
|
||||
## 更新日志
|
||||
* 2.2.7
|
||||
+ 新功能:`只建造节点不建造框架`
|
||||
+ 打开设置面板时不再关闭背包面板
|
||||
+ 在`移除部分不影响游戏逻辑的建造条件`启用时移除`输入方向冲突`的检查条件
|
||||
+ 修复导致`传送带信号替换格式`不切换传送带信号数字格式的问题
|
||||
* 2.2.6
|
||||
+ 新功能:`可用节点全部造完时停止弹射`
|
||||
+ 修复了在未完成的节点上吸收太阳帆的问题
|
||||
* 2.2.5
|
||||
+ 在同时启用`快速吸收`、`跳过子弹阶段`和`跳过吸收阶段`时,所有弹射的太阳帆会跳过所有中间环节立即吸收
|
||||
+ 修复了`快速吸收`在大部分节点已满时无法立即吸收所有太阳帆的问题
|
||||
+ 修复了与一些mod的兼容性问题
|
||||
* 2.2.4
|
||||
+ 新功能:`在行星视图中允许玩家操作`
|
||||
+ 修复了UI显示问题
|
||||
* 2.2.3
|
||||
+ 新功能:`移除部分不影响游戏逻辑的建造条件`
|
||||
+ 修复了与一些mod的兼容性问题
|
||||
* 2.2.2
|
||||
+ 新功能:`将游戏绑定给当前账号`
|
||||
+ 新子功能:`传送带信号替换格式`
|
||||
+ 修复了`初始化本行星`可能导致崩溃的问题
|
||||
+ 修复了`建造秒完成`中传送带建造的问题
|
||||
* 2.2.1
|
||||
+ 即使在启用`无条件建造`时依然检查矿机的建造条件
|
||||
+ 修复一个可能导致`无条件建造`不生效的问题
|
||||
* 2.2.0
|
||||
+ 添加了一些发电相关功能
|
||||
+ 为传送带信号物品生成添加了一个子功能,在统计面板模拟了原材料和中间产物的生产过程
|
||||
+ 从建筑师模式中分离了一些功能
|
||||
* 2.1.0
|
||||
+ 传送带信号物品生成
|
||||
+ 修复窗口显示优先级可能导致提示信息被主窗口遮挡的问题
|
||||
* 2.0.0
|
||||
+ 重构代码
|
||||
+ UI实现
|
||||
+ 添加了很多功能
|
||||
* 1.0.0
|
||||
+ 初始版本
|
||||
|
||||
## 使用说明
|
||||
|
||||
* 按 `` 左Alt+`(反引号) `` 键呼出主面板,可以在面板上修改快捷键。
|
||||
* 标题界面和行星小地图旁也有按钮呼出主面板。
|
||||
* 功能:
|
||||
+ 更严格的建造菜单热键检测,因此在按住Ctrl/Alt/Shift时不再会触发建造热键(0~9, F1~F10, X, U)
|
||||
+ 常规:
|
||||
+ 启用开发模式快捷键(使用说明见设置面板)
|
||||
+ 屏蔽异常检测
|
||||
+ 使用组合键解锁科技(Ctrl/Alt/Shift)
|
||||
+ 将游戏绑定给当前账号
|
||||
+ 工厂:
|
||||
+ 建造秒完成
|
||||
+ 建筑师模式(无限建筑)
|
||||
+ ** 无限交互距离
|
||||
+ 无条件建造
|
||||
+ ** 移除部分不影响游戏逻辑的建造条件
|
||||
+ 无碰撞
|
||||
+ ** 夜间日光灯
|
||||
+ 传送带信号物品生成
|
||||
+ 统计面板中计算所有原材料和中间产物
|
||||
+ 传送带信号替换格式
|
||||
+ 风力发电机和太阳能板无间距限制
|
||||
+ 提升各种发电设备发电量
|
||||
+ 行星:
|
||||
+ ** 在行星视图中允许玩家操作
|
||||
+ 自然资源采集不消耗
|
||||
+ 高速采集
|
||||
+ 平地抽水
|
||||
+ 沙土不够时依然可以整改地形
|
||||
+ ** 初始化本行星(不重置矿脉)
|
||||
+ ** 快速拆除所有建筑(不掉落)
|
||||
+ 戴森球:
|
||||
+ ** 可用节点全部造完时停止弹射
|
||||
+ ** 只建造节点不建造框架
|
||||
+ 跳过子弹阶段
|
||||
+ 跳过吸收阶段
|
||||
+ 快速吸收
|
||||
+ 全球弹射
|
||||
+ ** 初始化戴森球
|
||||
+ ** 快速拆除戴森壳
|
||||
+ 母星系:
|
||||
+ 母星有稀有资源
|
||||
+ 母星是纯平的
|
||||
+ 母星系恒星高亮
|
||||
|
||||
## 注意事项
|
||||
* 如果和[BlueprintTweaks](https://dsp.thunderstore.io/package/kremnev8/BlueprintTweaks/)一起使用,请升级`BepInEx`到5.4.21或更高版本,以避免可能的冲突。
|
||||
+ 你可以在[这里](https://github.com/bepinex/bepinex/releases/latest)(选择x64版本)下载`BepInEx`。
|
||||
+ 如果使用r2modman,你可以点击`Settings` -> `Browse profile folder`,然后将下载的zip解压到该文件夹并覆盖现有文件。
|
||||
|
||||
## 鸣谢
|
||||
* [戴森球计划](https://store.steampowered.com/app/1366540): 伟大的游戏
|
||||
* [BepInEx](https://bepinex.dev/): 基础模组框架
|
||||
* [Multifunction_mod](https://github.com/blacksnipebiu/Multifunction_mod): 一些作弊功能
|
||||
* [LSTM](https://github.com/hetima/DSP_LSTM) & [PlanetFinder](https://github.com/hetima/DSP_PlanetFinder): UI实现
|
||||
86
UXAssist/UI/MyCheckbox.cs
Normal file
86
UXAssist/UI/MyCheckbox.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using BepInEx.Configuration;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace UXAssist.UI;
|
||||
|
||||
// MyCheckBox modified from LSTM: https://github.com/hetima/DSP_LSTM/blob/main/LSTM/MyCheckBox.cs
|
||||
public class MyCheckBox : MonoBehaviour
|
||||
{
|
||||
public UIButton uiButton;
|
||||
public Image checkImage;
|
||||
public RectTransform rectTrans;
|
||||
public Text labelText;
|
||||
public event Action OnChecked;
|
||||
private bool _checked;
|
||||
private ConfigEntry<bool> _configAssigned;
|
||||
|
||||
public bool Checked
|
||||
{
|
||||
get => _checked;
|
||||
set
|
||||
{
|
||||
_checked = value;
|
||||
checkImage.enabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static MyCheckBox CreateCheckBox(float x, float y, RectTransform parent, ConfigEntry<bool> config, string label = "", int fontSize = 15)
|
||||
{
|
||||
var cb = CreateCheckBox(x, y, parent, config.Value, label, fontSize);
|
||||
cb._configAssigned = config;
|
||||
cb.OnChecked += () => config.Value = !config.Value;
|
||||
config.SettingChanged += (_, _) => cb.Checked = config.Value;
|
||||
return cb;
|
||||
}
|
||||
|
||||
public static MyCheckBox CreateCheckBox(float x, float y, RectTransform parent, bool check, string label = "", int fontSize = 15)
|
||||
{
|
||||
var buildMenu = UIRoot.instance.uiGame.buildMenu;
|
||||
var src = buildMenu.uxFacilityCheck;
|
||||
|
||||
var go = Instantiate(src.gameObject);
|
||||
go.name = "my-checkbox";
|
||||
var cb = go.AddComponent<MyCheckBox>();
|
||||
cb._checked = check;
|
||||
var rect = Util.NormalizeRectWithTopLeft(cb, x, y, parent);
|
||||
|
||||
cb.rectTrans = rect;
|
||||
cb.uiButton = go.GetComponent<UIButton>();
|
||||
cb.checkImage = go.transform.Find("checked")?.GetComponent<Image>();
|
||||
|
||||
var child = go.transform.Find("text");
|
||||
if (child != null)
|
||||
{
|
||||
DestroyImmediate(child.GetComponent<Localizer>());
|
||||
cb.labelText = child.GetComponent<Text>();
|
||||
cb.labelText.fontSize = fontSize;
|
||||
cb.SetLabelText(label);
|
||||
}
|
||||
|
||||
//value
|
||||
cb.uiButton.onClick += cb.OnClick;
|
||||
if (cb.checkImage != null)
|
||||
{
|
||||
cb.checkImage.enabled = check;
|
||||
}
|
||||
|
||||
return cb;
|
||||
}
|
||||
|
||||
public void SetLabelText(string val)
|
||||
{
|
||||
if (labelText != null)
|
||||
{
|
||||
labelText.text = val.Translate();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnClick(int obj)
|
||||
{
|
||||
_checked = !_checked;
|
||||
checkImage.enabled = _checked;
|
||||
OnChecked?.Invoke();
|
||||
}
|
||||
}
|
||||
64
UXAssist/UI/MyConfigWindow.cs
Normal file
64
UXAssist/UI/MyConfigWindow.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UXAssist.Common;
|
||||
|
||||
namespace UXAssist.UI;
|
||||
|
||||
public class MyConfigWindow : MyWindowWithTabs
|
||||
{
|
||||
public static Action<MyConfigWindow, RectTransform> OnUICreated;
|
||||
public static Action OnUpdateUI;
|
||||
|
||||
private RectTransform _windowTrans;
|
||||
|
||||
public static MyConfigWindow CreateInstance()
|
||||
{
|
||||
return MyWindowManager.CreateWindow<MyConfigWindow>("UXAConfigWindow", "UXAssist Config");
|
||||
}
|
||||
|
||||
public override void _OnCreate()
|
||||
{
|
||||
_windowTrans = GetComponent<RectTransform>();
|
||||
_windowTrans.sizeDelta = new Vector2(680f, 420f);
|
||||
|
||||
OnUICreated?.Invoke(this, _windowTrans);
|
||||
SetCurrentTab(0);
|
||||
OnUpdateUI?.Invoke();
|
||||
}
|
||||
|
||||
public override void _OnDestroy()
|
||||
{
|
||||
}
|
||||
|
||||
public override bool _OnInit()
|
||||
{
|
||||
_windowTrans.anchoredPosition = new Vector2(0, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void _OnFree()
|
||||
{
|
||||
}
|
||||
|
||||
public override void _OnOpen()
|
||||
{
|
||||
}
|
||||
|
||||
public override void _OnClose()
|
||||
{
|
||||
}
|
||||
|
||||
public override void _OnUpdate()
|
||||
{
|
||||
base._OnUpdate();
|
||||
if (VFInput.escape && !VFInput.inputing)
|
||||
{
|
||||
VFInput.UseEscape();
|
||||
_Close();
|
||||
return;
|
||||
}
|
||||
|
||||
OnUpdateUI?.Invoke();
|
||||
}
|
||||
}
|
||||
231
UXAssist/UI/MyKeyBinder.cs
Normal file
231
UXAssist/UI/MyKeyBinder.cs
Normal file
@@ -0,0 +1,231 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using BepInEx.Configuration;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace UXAssist.UI;
|
||||
|
||||
// MyKeyBinder modified from LSTM: https://github.com/hetima/DSP_LSTM/blob/main/LSTM/MyKeyBinder.cs
|
||||
public class MyKeyBinder : MonoBehaviour
|
||||
{
|
||||
private ConfigEntry<KeyboardShortcut> _config;
|
||||
|
||||
[SerializeField]
|
||||
public Text functionText;
|
||||
|
||||
[SerializeField]
|
||||
public Text keyText;
|
||||
|
||||
[SerializeField]
|
||||
public InputField setTheKeyInput;
|
||||
|
||||
[SerializeField]
|
||||
public Toggle setTheKeyToggle;
|
||||
|
||||
[SerializeField]
|
||||
public RectTransform rectTrans;
|
||||
|
||||
[SerializeField]
|
||||
public UIButton inputUIButton;
|
||||
|
||||
[SerializeField]
|
||||
public Text conflictText;
|
||||
|
||||
[SerializeField]
|
||||
public Text waitingText;
|
||||
|
||||
[SerializeField]
|
||||
public UIButton setDefaultUIButton;
|
||||
|
||||
[SerializeField]
|
||||
public UIButton setNoneKeyUIButton;
|
||||
|
||||
private bool _nextNotOn;
|
||||
|
||||
public static RectTransform CreateKeyBinder(float x, float y, RectTransform parent, ConfigEntry<KeyboardShortcut> config, string label = "", int fontSize = 17)
|
||||
{
|
||||
var optionWindow = UIRoot.instance.optionWindow;
|
||||
var uikeyEntry = Instantiate(optionWindow.entryPrefab);
|
||||
GameObject go;
|
||||
(go = uikeyEntry.gameObject).SetActive(true);
|
||||
go.name = "my-keybinder";
|
||||
var kb = go.AddComponent<MyKeyBinder>();
|
||||
kb._config = config;
|
||||
|
||||
kb.functionText = uikeyEntry.functionText;
|
||||
kb.keyText = uikeyEntry.keyText;
|
||||
kb.setTheKeyInput = uikeyEntry.setTheKeyInput;
|
||||
kb.setTheKeyToggle = uikeyEntry.setTheKeyToggle;
|
||||
kb.rectTrans = uikeyEntry.rectTrans;
|
||||
kb.inputUIButton = uikeyEntry.inputUIButton;
|
||||
kb.conflictText = uikeyEntry.conflictText;
|
||||
kb.waitingText = uikeyEntry.waitingText;
|
||||
kb.setDefaultUIButton = uikeyEntry.setDefaultUIButton;
|
||||
kb.setNoneKeyUIButton = uikeyEntry.setNoneKeyUIButton;
|
||||
|
||||
|
||||
kb.functionText.text = label.Translate();
|
||||
kb.functionText.fontSize = 17;
|
||||
|
||||
((RectTransform)kb.keyText.transform).anchoredPosition = new Vector2(20f, -27f);
|
||||
//kb.keyText.alignment = TextAnchor.MiddleRight;
|
||||
kb.keyText.fontSize = 17;
|
||||
((RectTransform)kb.inputUIButton.transform.parent.transform).anchoredPosition = new Vector2(0f + 20f, -57f);
|
||||
((RectTransform)kb.setDefaultUIButton.transform).anchoredPosition = new Vector2(140f + 20f, -57f);
|
||||
((RectTransform)kb.setNoneKeyUIButton.transform).anchoredPosition = new Vector2(240f + 20f, -57f);
|
||||
|
||||
var rect = Util.NormalizeRectWithTopLeft(kb, x, y, parent);
|
||||
kb.rectTrans = rect;
|
||||
|
||||
//rect.sizeDelta = new Vector2(240f, 64f);
|
||||
Destroy(uikeyEntry);
|
||||
kb.setNoneKeyUIButton.gameObject.SetActive(false);
|
||||
|
||||
kb.SettingChanged();
|
||||
config.SettingChanged += (_, _) => {
|
||||
kb.SettingChanged();
|
||||
};
|
||||
kb.inputUIButton.onClick += kb.OnInputUIButtonClick;
|
||||
kb.setDefaultUIButton.onClick += kb.OnSetDefaultKeyClick;
|
||||
//kb.setNoneKeyUIButton.onClick += kb.OnSetNoneKeyClick;
|
||||
return go.transform as RectTransform;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!setTheKeyToggle.isOn && inputUIButton.highlighted)
|
||||
{
|
||||
setTheKeyToggle.isOn = true;
|
||||
}
|
||||
|
||||
if (!setTheKeyToggle.isOn) return;
|
||||
if (!inputUIButton._isPointerEnter && Input.GetKeyDown(KeyCode.Mouse0))
|
||||
{
|
||||
inputUIButton.highlighted = false;
|
||||
setTheKeyToggle.isOn = false;
|
||||
Reset();
|
||||
}
|
||||
else if (!this.inputUIButton.highlighted)
|
||||
{
|
||||
setTheKeyToggle.isOn = false;
|
||||
Reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
waitingText.gameObject.SetActive(true);
|
||||
if (!TrySetValue()) return;
|
||||
setTheKeyToggle.isOn = false;
|
||||
inputUIButton.highlighted = false;
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool TrySetValue()
|
||||
{
|
||||
if (Input.GetKey(KeyCode.Escape))
|
||||
{
|
||||
VFInput.UseEscape();
|
||||
return true;
|
||||
}
|
||||
if (Input.GetKey(KeyCode.Mouse0) || Input.GetKey(KeyCode.Mouse1))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
var anyKey = GetIunptKeys();
|
||||
if (anyKey || _lastKey == KeyCode.None) return false;
|
||||
var k = GetPressedKey();
|
||||
if (string.IsNullOrEmpty(k))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_lastKey = KeyCode.None;
|
||||
|
||||
_config.Value = KeyboardShortcut.Deserialize(k);
|
||||
//keyText.text = k;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
private KeyCode _lastKey;
|
||||
private static readonly KeyCode[] ModKeys = { KeyCode.RightShift, KeyCode.LeftShift,
|
||||
KeyCode.RightControl, KeyCode.LeftControl,
|
||||
KeyCode.RightAlt, KeyCode.LeftAlt,
|
||||
KeyCode.LeftCommand, KeyCode.LeftApple, KeyCode.LeftWindows,
|
||||
KeyCode.RightCommand, KeyCode.RightApple, KeyCode.RightWindows };
|
||||
|
||||
public string GetPressedKey()
|
||||
{
|
||||
var key = _lastKey.ToString();
|
||||
if (string.IsNullOrEmpty(key))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var mod = "";
|
||||
foreach (var modKey in ModKeys)
|
||||
{
|
||||
if (Input.GetKey(modKey))
|
||||
{
|
||||
mod += "+" + modKey.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(mod))
|
||||
{
|
||||
key += mod;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
//通常キーが押されているかチェック _lastKey に保存
|
||||
public bool GetIunptKeys()
|
||||
{
|
||||
var anyKey = false;
|
||||
|
||||
foreach (KeyCode item in Enum.GetValues(typeof(KeyCode)))
|
||||
{
|
||||
if (item == KeyCode.None || ModKeys.Contains(item) || !Input.GetKey(item)) continue;
|
||||
_lastKey = item;
|
||||
anyKey = true;
|
||||
}
|
||||
return anyKey;
|
||||
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
conflictText.gameObject.SetActive(false);
|
||||
waitingText.gameObject.SetActive(false);
|
||||
setDefaultUIButton.button.Select(); // InputFieldのフォーカス外す
|
||||
_lastKey = KeyCode.None;
|
||||
}
|
||||
|
||||
public void OnInputUIButtonClick(int data)
|
||||
{
|
||||
inputUIButton.highlighted = true;
|
||||
|
||||
if (!_nextNotOn) return;
|
||||
_nextNotOn = false;
|
||||
inputUIButton.highlighted = false;
|
||||
setTheKeyToggle.isOn = false;
|
||||
waitingText.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
public void OnSetDefaultKeyClick(int data)
|
||||
{
|
||||
_config.Value = (KeyboardShortcut)_config.DefaultValue;
|
||||
keyText.text = _config.Value.Serialize();
|
||||
}
|
||||
|
||||
public void OnSetNoneKeyClick(int data)
|
||||
{
|
||||
_config.Value = (KeyboardShortcut)_config.DefaultValue;
|
||||
keyText.text = _config.Value.Serialize();
|
||||
}
|
||||
|
||||
public void SettingChanged()
|
||||
{
|
||||
keyText.text = _config.Value.Serialize();
|
||||
}
|
||||
}
|
||||
123
UXAssist/UI/MySlider.cs
Normal file
123
UXAssist/UI/MySlider.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace UXAssist.UI;
|
||||
|
||||
// MySlider modified from LSTM: https://github.com/hetima/DSP_LSTM/blob/main/LSTM/MySlider.cs
|
||||
|
||||
public class MySlider : MonoBehaviour
|
||||
{
|
||||
public Slider slider;
|
||||
public RectTransform rectTrans;
|
||||
public Text labelText;
|
||||
public string labelFormat;
|
||||
public event Action OnValueChanged;
|
||||
private float _value;
|
||||
public float Value
|
||||
{
|
||||
get => _value;
|
||||
set
|
||||
{
|
||||
_value = value;
|
||||
OnValueSet();
|
||||
}
|
||||
}
|
||||
|
||||
public static RectTransform CreateSlider(float x, float y, RectTransform parent, float value, float minValue, float maxValue, string format = "{0}", float width = 0f)
|
||||
{
|
||||
var optionWindow = UIRoot.instance.optionWindow;
|
||||
var src = optionWindow.audioVolumeComp;
|
||||
|
||||
var go = Instantiate(src.gameObject);
|
||||
//sizeDelta = 240, 20
|
||||
go.name = "my-slider";
|
||||
go.SetActive(true);
|
||||
var sl = go.AddComponent<MySlider>();
|
||||
sl._value = value;
|
||||
var rect = Util.NormalizeRectWithTopLeft(sl, x, y, parent);
|
||||
sl.rectTrans = rect;
|
||||
if (width > 0)
|
||||
{
|
||||
rect.sizeDelta = new Vector2(width, rect.sizeDelta.y);
|
||||
}
|
||||
|
||||
sl.slider = go.GetComponent<Slider>();
|
||||
sl.slider.minValue = minValue;
|
||||
sl.slider.maxValue = maxValue;
|
||||
sl.slider.onValueChanged.RemoveAllListeners();
|
||||
sl.slider.onValueChanged.AddListener(sl.SliderChanged);
|
||||
sl.labelText = sl.slider.handleRect.Find("Text")?.GetComponent<Text>();
|
||||
if (sl.labelText != null)
|
||||
{
|
||||
sl.labelText.fontSize = 14;
|
||||
if (sl.labelText.transform is RectTransform rectTrans)
|
||||
{
|
||||
rectTrans.sizeDelta = new Vector2(22f, 22f);
|
||||
}
|
||||
}
|
||||
sl.labelFormat = format;
|
||||
|
||||
var bg = sl.slider.transform.Find("Background")?.GetComponent<Image>();
|
||||
if (bg != null)
|
||||
{
|
||||
bg.color = new Color(0.5f, 0.5f, 0.5f, 0.5f);
|
||||
}
|
||||
var fill = sl.slider.fillRect.GetComponent<Image>();
|
||||
if (fill != null)
|
||||
{
|
||||
fill.color = new Color(1f, 1f, 1f, 0.28f);
|
||||
}
|
||||
sl.OnValueSet();
|
||||
sl.UpdateLabel();
|
||||
|
||||
return sl.rectTrans;
|
||||
}
|
||||
public void OnValueSet()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
var sliderVal = _value;
|
||||
if (_value.Equals(slider.value)) return;
|
||||
if (sliderVal > slider.maxValue)
|
||||
{
|
||||
_value = sliderVal = slider.maxValue;
|
||||
}
|
||||
else if (sliderVal < slider.minValue)
|
||||
{
|
||||
_value = sliderVal = slider.minValue;
|
||||
}
|
||||
|
||||
slider.value = sliderVal;
|
||||
UpdateLabel();
|
||||
}
|
||||
}
|
||||
public void UpdateLabel()
|
||||
{
|
||||
if (labelText != null)
|
||||
{
|
||||
labelText.text = _value.ToString(labelFormat);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetLabelText(string text)
|
||||
{
|
||||
if (labelText != null)
|
||||
{
|
||||
labelText.text = text;
|
||||
}
|
||||
}
|
||||
|
||||
public void SliderChanged(float val)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
var newVal = Mathf.Round(slider.value);
|
||||
if (_value.Equals(newVal)) return;
|
||||
_value = newVal;
|
||||
UpdateLabel();
|
||||
OnValueChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
427
UXAssist/UI/MyWindow.cs
Normal file
427
UXAssist/UI/MyWindow.cs
Normal file
@@ -0,0 +1,427 @@
|
||||
using System;
|
||||
using HarmonyLib;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.UI;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace UXAssist.UI;
|
||||
|
||||
// MyWindow modified from LSTM: https://github.com/hetima/DSP_LSTM/blob/main/LSTM/MyWindowCtl.cs
|
||||
|
||||
public class MyWindow: ManualBehaviour
|
||||
{
|
||||
private readonly Dictionary<InputField, Tuple<UnityAction<string>, UnityAction<string>>> _inputFields = new();
|
||||
private readonly Dictionary<UIButton, UnityAction> _buttons = new();
|
||||
protected bool EventRegistered { get; private set; }
|
||||
|
||||
public virtual void TryClose()
|
||||
{
|
||||
_Close();
|
||||
}
|
||||
|
||||
public virtual bool IsWindowFunctional()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Open()
|
||||
{
|
||||
_Open();
|
||||
transform.SetAsLastSibling();
|
||||
}
|
||||
|
||||
public void Close() => _Close();
|
||||
|
||||
public void SetTitle(string title)
|
||||
{
|
||||
var txt = gameObject.transform.Find("panel-bg/title-text")?.gameObject.GetComponent<Text>();
|
||||
if (txt)
|
||||
{
|
||||
txt.text = title.Translate();
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddElement(float x, float y, RectTransform rect, RectTransform parent = null)
|
||||
{
|
||||
if (rect != null)
|
||||
{
|
||||
Util.NormalizeRectWithTopLeft(rect, x, y, parent);
|
||||
}
|
||||
}
|
||||
|
||||
public static Text AddText(float x, float y, RectTransform parent, string label, int fontSize = 14, string objName = "label")
|
||||
{
|
||||
var src = UIRoot.instance.uiGame.assemblerWindow.stateText;
|
||||
var txt = Instantiate(src);
|
||||
txt.gameObject.name = objName;
|
||||
txt.text = label.Translate();
|
||||
txt.color = new Color(1f, 1f, 1f, 0.4f);
|
||||
txt.alignment = TextAnchor.MiddleLeft;
|
||||
txt.fontSize = fontSize;
|
||||
if (txt.transform is RectTransform rect)
|
||||
{
|
||||
rect.sizeDelta = new Vector2(txt.preferredWidth + 40f, 30f);
|
||||
}
|
||||
AddElement(x, y, txt.rectTransform, parent);
|
||||
return txt;
|
||||
}
|
||||
|
||||
public static UIButton AddTipsButton(float x, float y, RectTransform parent, string label, string tip, string content, string objName = "tips-button")
|
||||
{
|
||||
var src = UIRoot.instance.galaxySelect.sandboxToggle.gameObject.transform.parent.Find("tip-button");
|
||||
var dst = Instantiate(src);
|
||||
dst.gameObject.name = objName;
|
||||
var btn = dst.GetComponent<UIButton>();
|
||||
Util.NormalizeRectWithTopLeft(btn, x, y, parent);
|
||||
btn.tips.topLevel = true;
|
||||
btn.tips.tipTitle = label;
|
||||
btn.tips.tipText = tip;
|
||||
btn.UpdateTip();
|
||||
return btn;
|
||||
}
|
||||
|
||||
public UIButton AddButton(float x, float y, RectTransform parent, string text = "", int fontSize = 16, string objName = "button", UnityAction onClick = null)
|
||||
{
|
||||
var panel = UIRoot.instance.uiGame.statWindow.performancePanelUI;
|
||||
var btn = Instantiate(panel.cpuActiveButton);
|
||||
btn.gameObject.name = objName;
|
||||
var rect = Util.NormalizeRectWithTopLeft(btn, x, y, parent);
|
||||
rect.sizeDelta = new Vector2(150, rect.sizeDelta.y);
|
||||
var l = btn.gameObject.transform.Find("button-text").GetComponent<Localizer>();
|
||||
var t = btn.gameObject.transform.Find("button-text").GetComponent<Text>();
|
||||
if (l != null)
|
||||
{
|
||||
l.stringKey = text;
|
||||
l.translation = text.Translate();
|
||||
}
|
||||
if (t != null)
|
||||
{
|
||||
t.text = text.Translate();
|
||||
}
|
||||
t.fontSize = fontSize;
|
||||
btn.button.onClick.RemoveAllListeners();
|
||||
btn.tip = null;
|
||||
btn.tips = new UIButton.TipSettings();
|
||||
_buttons[btn] = onClick;
|
||||
if (EventRegistered)
|
||||
{
|
||||
if (onClick != null)
|
||||
btn.button.onClick.AddListener(onClick);
|
||||
}
|
||||
return btn;
|
||||
}
|
||||
|
||||
public UIButton AddFlatButton(float x, float y, RectTransform parent, string text = "", int fontSize = 12, string objName = "button", UnityAction onClick = null)
|
||||
{
|
||||
var panel = UIRoot.instance.uiGame.dysonEditor.controlPanel.hierarchy.layerPanel;
|
||||
var btn = Instantiate(panel.layerButtons[0]);
|
||||
btn.gameObject.name = objName;
|
||||
btn.highlighted = false;
|
||||
Util.NormalizeRectWithTopLeft(btn, x, y, parent);
|
||||
var t = btn.gameObject.transform.Find("Text").GetComponent<Text>();
|
||||
if (t != null)
|
||||
{
|
||||
t.text = text.Translate();
|
||||
}
|
||||
t.fontSize = fontSize;
|
||||
btn.button.onClick.RemoveAllListeners();
|
||||
_buttons[btn] = onClick;
|
||||
if (EventRegistered)
|
||||
{
|
||||
if (onClick != null)
|
||||
btn.button.onClick.AddListener(onClick);
|
||||
}
|
||||
return btn;
|
||||
}
|
||||
|
||||
protected InputField AddInputField(float x, float y, RectTransform parent, string text = "", int fontSize = 16, string objName = "input", UnityAction<string> onChanged = null, UnityAction<string> onEditEnd = null)
|
||||
{
|
||||
var stationWindow = UIRoot.instance.uiGame.stationWindow;
|
||||
//public InputField nameInput;
|
||||
var inputField = Instantiate(stationWindow.nameInput);
|
||||
inputField.gameObject.name = objName;
|
||||
Destroy(inputField.GetComponent<UIButton>());
|
||||
inputField.GetComponent<Image>().color = new Color(1f, 1f, 1f, 0.05f);
|
||||
var rect = Util.NormalizeRectWithTopLeft(inputField, x, y, parent);
|
||||
rect.sizeDelta = new Vector2(210, rect.sizeDelta.y);
|
||||
inputField.textComponent.text = text;
|
||||
inputField.textComponent.fontSize = fontSize;
|
||||
inputField.onValueChanged.RemoveAllListeners();
|
||||
inputField.onEndEdit.RemoveAllListeners();
|
||||
_inputFields[inputField] = Tuple.Create(onChanged, onEditEnd);
|
||||
if (EventRegistered)
|
||||
{
|
||||
if (onChanged != null)
|
||||
inputField.onValueChanged.AddListener(onChanged);
|
||||
if (onEditEnd != null)
|
||||
inputField.onEndEdit.AddListener(onEditEnd);
|
||||
}
|
||||
return inputField;
|
||||
}
|
||||
|
||||
public override void _OnRegEvent()
|
||||
{
|
||||
base._OnRegEvent();
|
||||
if (EventRegistered) return;
|
||||
foreach (var t in _inputFields)
|
||||
{
|
||||
var inputField = t.Key;
|
||||
if (t.Value.Item1 != null)
|
||||
inputField.onValueChanged.AddListener(t.Value.Item1);
|
||||
if (t.Value.Item2 != null)
|
||||
inputField.onEndEdit.AddListener(t.Value.Item2);
|
||||
}
|
||||
foreach (var t in _buttons)
|
||||
{
|
||||
var btn = t.Key;
|
||||
if (t.Value != null)
|
||||
btn.button.onClick.AddListener(t.Value);
|
||||
}
|
||||
EventRegistered = true;
|
||||
}
|
||||
|
||||
public override void _OnUnregEvent()
|
||||
{
|
||||
base._OnUnregEvent();
|
||||
if (!EventRegistered) return;
|
||||
EventRegistered = false;
|
||||
foreach (var t in _buttons)
|
||||
{
|
||||
var btn = t.Key;
|
||||
if (t.Value != null)
|
||||
btn.button.onClick.RemoveListener(t.Value);
|
||||
}
|
||||
foreach (var t in _inputFields)
|
||||
{
|
||||
var inputField = t.Key;
|
||||
if (t.Value.Item1 != null)
|
||||
inputField.onValueChanged.RemoveListener(t.Value.Item1);
|
||||
if (t.Value.Item2 != null)
|
||||
inputField.onEndEdit.RemoveListener(t.Value.Item2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class MyWindowWithTabs : MyWindow
|
||||
{
|
||||
private readonly List<Tuple<RectTransform, UIButton>> _tabs = new();
|
||||
private float _tabX = 36f;
|
||||
public override void TryClose()
|
||||
{
|
||||
_Close();
|
||||
}
|
||||
|
||||
public override bool IsWindowFunctional()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public RectTransform AddTab(float x, int index, RectTransform parent, string label)
|
||||
{
|
||||
var tab = new GameObject();
|
||||
var tabRect = tab.AddComponent<RectTransform>();
|
||||
Util.NormalizeRectWithMargin(tabRect, 54f + 28f, 36f, 0f, 0f, parent);
|
||||
tab.name = "tab-" + index;
|
||||
var swarmPanel = UIRoot.instance.uiGame.dysonEditor.controlPanel.hierarchy.swarmPanel;
|
||||
var src = swarmPanel.orbitButtons[0];
|
||||
var btn = Instantiate(src);
|
||||
var btnRect = Util.NormalizeRectWithTopLeft(btn, x, 54f, parent);
|
||||
btn.name = "tab-btn-" + index;
|
||||
btnRect.sizeDelta = new Vector2(100f, 24f);
|
||||
btn.transform.Find("frame").gameObject.SetActive(false);
|
||||
if (btn.transitions.Length >= 3)
|
||||
{
|
||||
btn.transitions[0].normalColor = new Color(0.1f, 0.1f, 0.1f, 0.68f);
|
||||
btn.transitions[0].highlightColorOverride = new Color(0.9906f, 0.5897f, 0.3691f, 0.4f);
|
||||
btn.transitions[1].normalColor = new Color(1f, 1f, 1f, 0.6f);
|
||||
btn.transitions[1].highlightColorOverride = new Color(0.2f, 0.1f, 0.1f, 0.9f);
|
||||
}
|
||||
|
||||
var btnText = btn.transform.Find("Text").GetComponent<Text>();
|
||||
btnText.text = label.Translate();
|
||||
btnText.fontSize = 16;
|
||||
btn.data = index;
|
||||
|
||||
_tabs.Add(Tuple.Create(tabRect, btn));
|
||||
if (EventRegistered)
|
||||
{
|
||||
btn.onClick += OnTabButtonClick;
|
||||
}
|
||||
return tabRect;
|
||||
}
|
||||
|
||||
public RectTransform AddTab(RectTransform parent, string label)
|
||||
{
|
||||
var result = AddTab(_tabX, _tabs.Count, parent, label);
|
||||
_tabX += 100f;
|
||||
return result;
|
||||
}
|
||||
|
||||
public override void _OnRegEvent()
|
||||
{
|
||||
if (!EventRegistered)
|
||||
{
|
||||
foreach (var t in _tabs)
|
||||
{
|
||||
t.Item2.onClick += OnTabButtonClick;
|
||||
}
|
||||
}
|
||||
base._OnRegEvent();
|
||||
}
|
||||
|
||||
public override void _OnUnregEvent()
|
||||
{
|
||||
if (EventRegistered)
|
||||
{
|
||||
foreach (var t in _tabs)
|
||||
{
|
||||
t.Item2.onClick -= OnTabButtonClick;
|
||||
}
|
||||
}
|
||||
base._OnUnregEvent();
|
||||
}
|
||||
|
||||
protected void SetCurrentTab(int index) => OnTabButtonClick(index);
|
||||
|
||||
private void OnTabButtonClick(int index)
|
||||
{
|
||||
foreach (var (rectTransform, btn) in _tabs)
|
||||
{
|
||||
if (btn.data != index)
|
||||
{
|
||||
btn.highlighted = false;
|
||||
rectTransform.gameObject.SetActive(false);
|
||||
continue;
|
||||
}
|
||||
btn.highlighted = true;
|
||||
rectTransform.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyWindowManager
|
||||
{
|
||||
private static readonly List<ManualBehaviour> Windows = new(4);
|
||||
private static bool _initialized;
|
||||
|
||||
public static T CreateWindow<T>(string name, string title = "") where T : MyWindow
|
||||
{
|
||||
var srcWin = UIRoot.instance.uiGame.tankWindow;
|
||||
var src = srcWin.gameObject;
|
||||
var go = Object.Instantiate(src, UIRoot.instance.uiGame.transform.parent);
|
||||
go.name = name;
|
||||
go.SetActive(false);
|
||||
Object.Destroy(go.GetComponent<UITankWindow>());
|
||||
var win = go.AddComponent<T>() as MyWindow;
|
||||
if (win == null)
|
||||
return null;
|
||||
|
||||
for (var i = 0; i < go.transform.childCount; i++)
|
||||
{
|
||||
var child = go.transform.GetChild(i).gameObject;
|
||||
if (child.name == "panel-bg")
|
||||
{
|
||||
var btn = child.GetComponentInChildren<Button>();
|
||||
//close-btn
|
||||
if (btn != null)
|
||||
{
|
||||
btn.onClick.AddListener(win._Close);
|
||||
}
|
||||
}
|
||||
else if (child.name != "shadow" && child.name != "panel-bg")
|
||||
{
|
||||
Object.Destroy(child);
|
||||
}
|
||||
}
|
||||
|
||||
win.SetTitle(title);
|
||||
win._Create();
|
||||
if (_initialized)
|
||||
{
|
||||
win._Init(win.data);
|
||||
}
|
||||
Windows.Add(win);
|
||||
return (T)win;
|
||||
}
|
||||
|
||||
/*
|
||||
public static void SetRect(ManualBehaviour win, RectTransform rect)
|
||||
{
|
||||
var rectTransform = win.GetComponent<RectTransform>();
|
||||
//rectTransform.position =
|
||||
//rectTransform.sizeDelta = rect;
|
||||
}
|
||||
*/
|
||||
|
||||
public static class Patch
|
||||
{
|
||||
|
||||
/*
|
||||
//_Create -> _Init
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(UIGame), "_OnCreate")]
|
||||
public static void UIGame__OnCreate_Postfix()
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(UIRoot), "_OnDestroy")]
|
||||
public static void UIRoot__OnDestroy_Postfix()
|
||||
{
|
||||
foreach (var win in Windows)
|
||||
{
|
||||
win._Free();
|
||||
win._Destroy();
|
||||
}
|
||||
Windows.Clear();
|
||||
}
|
||||
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(UIRoot), "_OnOpen")]
|
||||
public static void UIRoot__OnOpen_Postfix()
|
||||
{
|
||||
if (_initialized) return;
|
||||
foreach (var win in Windows)
|
||||
{
|
||||
win._Init(win.data);
|
||||
}
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
/*
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(UIGame), "_OnFree")]
|
||||
public static void UIGame__OnFree_Postfix()
|
||||
{
|
||||
foreach (var win in Windows)
|
||||
{
|
||||
win._Free();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(UIRoot), "_OnUpdate")]
|
||||
public static void UIRoot__OnUpdate_Postfix()
|
||||
{
|
||||
if (GameMain.isPaused || !GameMain.isRunning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (var win in Windows)
|
||||
{
|
||||
win._Update();
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(UIGame), "ShutAllFunctionWindow")]
|
||||
public static void UIGame_ShutAllFunctionWindow_Postfix()
|
||||
{
|
||||
foreach (var win in Windows)
|
||||
{
|
||||
if (win is MyWindow theWin && theWin.IsWindowFunctional())
|
||||
{
|
||||
theWin.TryClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
66
UXAssist/UI/Util.cs
Normal file
66
UXAssist/UI/Util.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace UXAssist.UI;
|
||||
|
||||
public static class Util
|
||||
{
|
||||
|
||||
public static RectTransform NormalizeRectWithTopLeft(Component cmp, float left, float top, Transform parent = null)
|
||||
{
|
||||
if (cmp.transform is not RectTransform rect) return null;
|
||||
if (parent != null)
|
||||
{
|
||||
rect.SetParent(parent, false);
|
||||
}
|
||||
rect.anchorMax = new Vector2(0f, 1f);
|
||||
rect.anchorMin = new Vector2(0f, 1f);
|
||||
rect.pivot = new Vector2(0f, 1f);
|
||||
rect.anchoredPosition3D = new Vector3(left, -top, 0f);
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static RectTransform NormalizeRectWithBottomLeft(Component cmp, float left, float bottom, Transform parent = null)
|
||||
{
|
||||
if (cmp.transform is not RectTransform rect) return null;
|
||||
if (parent != null)
|
||||
{
|
||||
rect.SetParent(parent, false);
|
||||
}
|
||||
rect.anchorMax = new Vector2(0f, 0f);
|
||||
rect.anchorMin = new Vector2(0f, 0f);
|
||||
rect.pivot = new Vector2(0f, 0f);
|
||||
rect.anchoredPosition3D = new Vector3(left, bottom, 0f);
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static RectTransform NormalizeRectWithMargin(Component cmp, float top, float left, float bottom, float right, Transform parent = null)
|
||||
{
|
||||
if (cmp.transform is not RectTransform rect) return null;
|
||||
if (parent != null)
|
||||
{
|
||||
rect.SetParent(parent, false);
|
||||
}
|
||||
rect.anchoredPosition3D = Vector3.zero;
|
||||
rect.localScale = Vector3.one;
|
||||
rect.anchorMax = Vector2.one;
|
||||
rect.anchorMin = Vector2.zero;
|
||||
rect.pivot = new Vector2(0.5f, 0.5f);
|
||||
rect.offsetMax = new Vector2(-right, -top);
|
||||
rect.offsetMin = new Vector2(left, bottom);
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static RectTransform NormalizeRectCenter(GameObject go, float width = 0, float height = 0)
|
||||
{
|
||||
if (go.transform is not RectTransform rect) return null;
|
||||
rect.anchorMax = new Vector2(0.5f, 0.5f);
|
||||
rect.anchorMin = new Vector2(0.5f, 0.5f);
|
||||
rect.pivot = new Vector2(0.5f, 0.5f);
|
||||
if (width > 0 && height > 0)
|
||||
{
|
||||
rect.sizeDelta = new Vector2(width, height);
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
|
||||
}
|
||||
26
UXAssist/UIConfigWindow.cs
Normal file
26
UXAssist/UIConfigWindow.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UXAssist.UI;
|
||||
using UXAssist.Common;
|
||||
|
||||
namespace UXAssist;
|
||||
|
||||
public static class UIConfigWindow
|
||||
{
|
||||
private static RectTransform _windowTrans;
|
||||
private static MyConfigWindow _configWindow;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
I18N.Add("UXAssist", "UXAssist", "UX助手");
|
||||
I18N.Apply();
|
||||
MyConfigWindow.OnUICreated += CreateUI;
|
||||
}
|
||||
|
||||
private static void CreateUI(MyConfigWindow wnd, RectTransform trans)
|
||||
{
|
||||
_configWindow = wnd;
|
||||
_windowTrans = trans;
|
||||
var tab1 = wnd.AddTab(_windowTrans, "UXAssist");
|
||||
}
|
||||
}
|
||||
285
UXAssist/UXAssist.cs
Normal file
285
UXAssist/UXAssist.cs
Normal file
@@ -0,0 +1,285 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection.Emit;
|
||||
using BepInEx;
|
||||
using BepInEx.Configuration;
|
||||
using HarmonyLib;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UXAssist.Common;
|
||||
using UXAssist.UI;
|
||||
|
||||
namespace UXAssist;
|
||||
|
||||
[BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)]
|
||||
public class UXAssist : BaseUnityPlugin
|
||||
{
|
||||
public new static readonly BepInEx.Logging.ManualLogSource Logger =
|
||||
BepInEx.Logging.Logger.CreateLogSource(PluginInfo.PLUGIN_NAME);
|
||||
|
||||
public static ConfigEntry<KeyboardShortcut> Hotkey;
|
||||
private static bool _configWinInitialized = false;
|
||||
private static MyConfigWindow _configWin;
|
||||
|
||||
private static Harmony _windowPatch;
|
||||
private static Harmony _patch;
|
||||
|
||||
private static bool _initialized;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Hotkey = Config.Bind("General", "Shortcut", KeyboardShortcut.Deserialize("BackQuote + LeftAlt"), "Shortcut to open config window");
|
||||
/*
|
||||
DevShortcuts.Enabled = Config.Bind("General", "DevShortcuts", false, "Enable DevMode shortcuts");
|
||||
AbnormalDisabler.Enabled = Config.Bind("General", "DisableAbnormalChecks", false,
|
||||
"disable all abnormal checks");
|
||||
TechPatch.Enabled = Config.Bind("General", "UnlockTech", false,
|
||||
"Unlock clicked tech by holding key-modifilers(Shift/Alt/Ctrl)");
|
||||
FactoryPatch.ImmediateEnabled = Config.Bind("Build", "ImmediateBuild", false,
|
||||
"Build immediately");
|
||||
FactoryPatch.ArchitectModeEnabled = Config.Bind("Build", "Architect", false,
|
||||
"Architect Mode");
|
||||
FactoryPatch.UnlimitInteractiveEnabled = Config.Bind("Build", "UnlimitInteractive", false,
|
||||
"Unlimit interactive range");
|
||||
FactoryPatch.RemoveSomeConditionEnabled = Config.Bind("Build", "RemoveSomeBuildConditionCheck", false,
|
||||
"Remove part of build condition checks that does not affect game logic");
|
||||
FactoryPatch.NoConditionEnabled = Config.Bind("Build", "BuildWithoutCondition", false,
|
||||
"Build without condition");
|
||||
FactoryPatch.NoCollisionEnabled = Config.Bind("Build", "NoCollision", false,
|
||||
"No collision");
|
||||
FactoryPatch.BeltSignalGeneratorEnabled = Config.Bind("Build", "BeltSignalGenerator", false,
|
||||
"Belt signal generator");
|
||||
FactoryPatch.BeltSignalNumberAltFormat = Config.Bind("Build", "BeltSignalNumberFormat", false,
|
||||
"Belt signal number format alternative format (AAAA=generation speed in minutes, B=proliferate points, C=stack count):\n AAAABC by default\n BCAAAA as alternative");
|
||||
FactoryPatch.BeltSignalCountRecipeEnabled = Config.Bind("Build", "BeltSignalCountRecipe", false,
|
||||
"Belt signal count all raws and intermediates in statistics");
|
||||
FactoryPatch.NightLightEnabled = Config.Bind("Build", "NightLight", false,
|
||||
"Night light");
|
||||
FactoryPatch.RemovePowerSpaceLimitEnabled = Config.Bind("Build", "RemovePowerDistanceLimit", false,
|
||||
"Remove distance limit for wind turbines and geothermals");
|
||||
FactoryPatch.BoostWindPowerEnabled = Config.Bind("Build", "BoostWindPower", false,
|
||||
"Boost wind power");
|
||||
FactoryPatch.BoostSolarPowerEnabled = Config.Bind("Build", "BoostSolarPower", false,
|
||||
"Boost solar power");
|
||||
FactoryPatch.BoostFuelPowerEnabled = Config.Bind("Build", "BoostFuelPower", false,
|
||||
"Boost fuel power");
|
||||
FactoryPatch.BoostGeothermalPowerEnabled = Config.Bind("Build", "BoostGeothermalPower", false,
|
||||
"Boost geothermal power");
|
||||
PlanetFunctions.PlayerActionsInGlobeViewEnabled = Config.Bind("Planet", "PlayerActionsInGlobeView", false,
|
||||
"Enable player actions in globe view");
|
||||
ResourcePatch.InfiniteResourceEnabled = Config.Bind("Planet", "AlwaysInfiniteResource", false,
|
||||
"always infinite natural resource");
|
||||
ResourcePatch.FastMiningEnabled = Config.Bind("Planet", "FastMining", false,
|
||||
"super-fast mining speed");
|
||||
WaterPumperPatch.Enabled = Config.Bind("Planet", "WaterPumpAnywhere", false,
|
||||
"Can pump water anywhere (while water type is not None)");
|
||||
TerraformPatch.Enabled = Config.Bind("Planet", "TerraformAnyway", false,
|
||||
"Can do terraform without enough sands");
|
||||
DysonSpherePatch.StopEjectOnNodeCompleteEnabled = Config.Bind("DysonSphere", "StopEjectOnNodeComplete", false,
|
||||
"Stop ejectors when available nodes are all filled up");
|
||||
DysonSpherePatch.OnlyConstructNodesEnabled = Config.Bind("DysonSphere", "OnlyConstructNodes", false,
|
||||
"Construct only nodes but frames");
|
||||
DysonSpherePatch.SkipBulletEnabled = Config.Bind("DysonSphere", "SkipBullet", false,
|
||||
"Skip bullet");
|
||||
DysonSpherePatch.SkipAbsorbEnabled = Config.Bind("DysonSphere", "SkipAbsorb", false,
|
||||
"Skip absorption");
|
||||
DysonSpherePatch.QuickAbsorbEnabled = Config.Bind("DysonSphere", "QuickAbsorb", false,
|
||||
"Quick absorb");
|
||||
DysonSpherePatch.EjectAnywayEnabled = Config.Bind("DysonSphere", "EjectAnyway", false,
|
||||
"Eject anyway");
|
||||
DysonSpherePatch.OverclockEjectorEnabled = Config.Bind("DysonSphere", "OverclockEjector", false,
|
||||
"Overclock ejector");
|
||||
DysonSpherePatch.OverclockSiloEnabled = Config.Bind("DysonSphere", "OverclockSilo", false,
|
||||
"Overclock silo");
|
||||
BirthPlanetPatch.SitiVeinsOnBirthPlanet = Config.Bind("Birth", "SiTiVeinsOnBirthPlanet", false,
|
||||
"Silicon/Titanium on birth planet");
|
||||
BirthPlanetPatch.FireIceOnBirthPlanet = Config.Bind("Birth", "FireIceOnBirthPlanet", false,
|
||||
"Fire ice on birth planet");
|
||||
BirthPlanetPatch.KimberliteOnBirthPlanet = Config.Bind("Birth", "KimberliteOnBirthPlanet", false,
|
||||
"Kimberlite on birth planet");
|
||||
BirthPlanetPatch.FractalOnBirthPlanet = Config.Bind("Birth", "FractalOnBirthPlanet", false,
|
||||
"Fractal silicon on birth planet");
|
||||
BirthPlanetPatch.OrganicOnBirthPlanet = Config.Bind("Birth", "OrganicOnBirthPlanet", false,
|
||||
"Organic crystal on birth planet");
|
||||
BirthPlanetPatch.OpticalOnBirthPlanet = Config.Bind("Birth", "OpticalOnBirthPlanet", false,
|
||||
"Optical grating crystal on birth planet");
|
||||
BirthPlanetPatch.SpiniformOnBirthPlanet = Config.Bind("Birth", "SpiniformOnBirthPlanet", false,
|
||||
"Spiniform stalagmite crystal on birth planet");
|
||||
BirthPlanetPatch.UnipolarOnBirthPlanet = Config.Bind("Birth", "UnipolarOnBirthPlanet", false,
|
||||
"Unipolar magnet on birth planet");
|
||||
BirthPlanetPatch.FlatBirthPlanet = Config.Bind("Birth", "FlatBirthPlanet", false,
|
||||
"Birth planet is solid flat (no water at all)");
|
||||
BirthPlanetPatch.HighLuminosityBirthStar = Config.Bind("Birth", "HighLuminosityBirthStar", false,
|
||||
"Birth star has high luminosity");
|
||||
*/
|
||||
I18N.Init();
|
||||
I18N.Add("UXAssist Config", "UXAssist Config", "UX助手设置");
|
||||
I18N.Apply();
|
||||
|
||||
// UI Patch
|
||||
_windowPatch ??= Harmony.CreateAndPatchAll(typeof(UI.MyWindowManager.Patch));
|
||||
_patch ??= Harmony.CreateAndPatchAll(typeof(UXAssist));
|
||||
|
||||
UIConfigWindow.Init();
|
||||
/*
|
||||
DevShortcuts.Init();
|
||||
AbnormalDisabler.Init();
|
||||
TechPatch.Init();
|
||||
FactoryPatch.Init();
|
||||
PlanetFunctions.Init();
|
||||
ResourcePatch.Init();
|
||||
WaterPumperPatch.Init();
|
||||
TerraformPatch.Init();
|
||||
DysonSpherePatch.Init();
|
||||
BirthPlanetPatch.Init();
|
||||
*/
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
/*
|
||||
BirthPlanetPatch.Uninit();
|
||||
DysonSpherePatch.Uninit();
|
||||
TerraformPatch.Uninit();
|
||||
WaterPumperPatch.Uninit();
|
||||
ResourcePatch.Uninit();
|
||||
PlanetFunctions.Uninit();
|
||||
FactoryPatch.Uninit();
|
||||
TechPatch.Uninit();
|
||||
AbnormalDisabler.Uninit();
|
||||
DevShortcuts.Uninit();
|
||||
*/
|
||||
_patch?.UnpatchSelf();
|
||||
_patch = null;
|
||||
_windowPatch?.UnpatchSelf();
|
||||
_windowPatch = null;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (VFInput.inputing) return;
|
||||
if (Hotkey.Value.IsDown()) ToggleConfigWindow();
|
||||
}
|
||||
/*
|
||||
private void LateUpdate()
|
||||
{
|
||||
FactoryPatch.NightLight.LateUpdate();
|
||||
}
|
||||
*/
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(UIRoot), nameof(UIRoot.OpenMainMenuUI))]
|
||||
public static void UIRoot_OpenMainMenuUI_Postfix()
|
||||
{
|
||||
if (_initialized) return;
|
||||
{
|
||||
var mainMenu = UIRoot.instance.uiMainMenu;
|
||||
var src = mainMenu.newGameButton;
|
||||
var parent = src.transform.parent;
|
||||
var btn = Instantiate(src, parent);
|
||||
btn.name = "button-cheatenabler-config";
|
||||
var l = btn.text.GetComponent<Localizer>();
|
||||
if (l != null)
|
||||
{
|
||||
l.stringKey = "CheatEnabler Config";
|
||||
l.translation = "CheatEnabler Config".Translate();
|
||||
}
|
||||
btn.text.text = "CheatEnabler Config".Translate();
|
||||
btn.text.fontSize = btn.text.fontSize * 7 / 8;
|
||||
I18N.OnInitialized += () => { btn.text.text = "UXAssist Config".Translate(); };
|
||||
var vec = ((RectTransform)mainMenu.exitButton.transform).anchoredPosition3D;
|
||||
var vec2 = ((RectTransform)mainMenu.creditsButton.transform).anchoredPosition3D;
|
||||
var transform1 = (RectTransform)btn.transform;
|
||||
transform1.anchoredPosition3D = new Vector3(vec.x, vec.y + (vec.y - vec2.y) * 2, vec.z);
|
||||
btn.button.onClick.RemoveAllListeners();
|
||||
btn.button.onClick.AddListener(ToggleConfigWindow);
|
||||
}
|
||||
{
|
||||
var panel = UIRoot.instance.uiGame.planetGlobe;
|
||||
var src = panel.button2;
|
||||
var sandboxMenu = UIRoot.instance.uiGame.sandboxMenu;
|
||||
var icon = sandboxMenu.categoryButtons[6].transform.Find("icon")?.GetComponent<Image>()?.sprite;
|
||||
var b = Instantiate(src, src.transform.parent);
|
||||
var panelButtonGo = b.gameObject;
|
||||
var rect = (RectTransform)panelButtonGo.transform;
|
||||
var btn = panelButtonGo.GetComponent<UIButton>();
|
||||
var img = panelButtonGo.transform.Find("button-2/icon")?.GetComponent<Image>();
|
||||
if (img != null)
|
||||
{
|
||||
img.sprite = icon;
|
||||
}
|
||||
if (panelButtonGo != null && btn != null)
|
||||
{
|
||||
panelButtonGo.name = "open-uxassist-config";
|
||||
rect.localScale = new Vector3(0.5f, 0.5f, 0.5f);
|
||||
rect.anchoredPosition3D = new Vector3(128f, -105f, 0f);
|
||||
b.onClick.RemoveAllListeners();
|
||||
btn.onClick += _ => { ToggleConfigWindow(); };
|
||||
btn.tips.tipTitle = "CheatEnabler Config";
|
||||
I18N.OnInitialized += () => { btn.tips.tipTitle = "UXAssist Config".Translate(); };
|
||||
btn.tips.tipText = null;
|
||||
btn.tips.corner = 9;
|
||||
btn.tips.offset = new Vector2(-20f, -20f);
|
||||
panelButtonGo.SetActive(true);
|
||||
}
|
||||
}
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(UIBuildMenu), nameof(UIBuildMenu._OnUpdate))]
|
||||
private static IEnumerable<CodeInstruction> UIBuildMenu__OnUpdate_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldsfld, AccessTools.Field(typeof(VFInput), nameof(VFInput.inScreen)))
|
||||
);
|
||||
matcher.Repeat(codeMatcher =>
|
||||
{
|
||||
var jumpPos = codeMatcher.Advance(1).Operand;
|
||||
codeMatcher.Advance(-1).InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(VFInput), nameof(VFInput.noModifier))),
|
||||
new CodeInstruction(OpCodes.Brfalse_S, jumpPos)
|
||||
).Advance(2);
|
||||
});
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(UIButton), nameof(UIButton.LateUpdate))]
|
||||
private static IEnumerable<CodeInstruction> UIButton_LateUpdate_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldloc_2),
|
||||
new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Component), nameof(Component.gameObject))),
|
||||
new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(GameObject), nameof(GameObject.activeSelf)))
|
||||
);
|
||||
var labels = matcher.Labels;
|
||||
matcher.Labels = null;
|
||||
matcher.Insert(
|
||||
new CodeInstruction(OpCodes.Ldloc_2).WithLabels(labels),
|
||||
new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Component), nameof(Component.transform))),
|
||||
new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Transform), nameof(Transform.parent))),
|
||||
new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Transform), nameof(Transform.parent))),
|
||||
new CodeInstruction(OpCodes.Callvirt, AccessTools.Method(typeof(Transform), nameof(Transform.SetAsLastSibling)))
|
||||
);
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
private static void ToggleConfigWindow()
|
||||
{
|
||||
if (!_configWinInitialized)
|
||||
{
|
||||
if (!I18N.Initialized()) return;
|
||||
_configWinInitialized = true;
|
||||
_configWin = MyConfigWindow.CreateInstance();
|
||||
}
|
||||
|
||||
if (_configWin.active)
|
||||
{
|
||||
_configWin._Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
_configWin.Open();
|
||||
}
|
||||
}
|
||||
}
|
||||
28
UXAssist/UXAssist.csproj
Normal file
28
UXAssist/UXAssist.csproj
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<BepInExPluginGuid>org.soardev.uxassist</BepInExPluginGuid>
|
||||
<Description>DSP MOD - UXAssist</Description>
|
||||
<Version>1.0.0</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<PackageId>UXAssist</PackageId>
|
||||
<RootNamespace>UXAssist</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BepInEx.Core" Version="5.*" />
|
||||
<PackageReference Include="BepInEx.PluginInfoProps" Version="1.*" />
|
||||
<PackageReference Include="DysonSphereProgram.GameLibs" Version="*-r.*" />
|
||||
<PackageReference Include="UnityEngine.Modules" Version="2018.4.12" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'">
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||
<Exec Command="del /F /Q package\$(ProjectName)-$(Version).zip
zip -9 -j package/$(ProjectName)-$(Version).zip $(TargetPath) package/icon.png package/manifest.json README.md" />
|
||||
</Target>
|
||||
</Project>
|
||||
BIN
UXAssist/package/icon.png
Normal file
BIN
UXAssist/package/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
9
UXAssist/package/manifest.json
Normal file
9
UXAssist/package/manifest.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "UXAssist",
|
||||
"version_number": "1.0.0",
|
||||
"website_url": "https://github.com/soarqin/DSP_Mods/tree/master/UXAssist",
|
||||
"description": "Some functions and patches for better user experience / 一些提升用户体验的功能和补丁",
|
||||
"dependencies": [
|
||||
"xiaoye97-BepInEx-5.4.17"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user