diff --git a/.travis/build-linux.bash b/.travis/build-linux.bash index c6c9487..88eec58 100755 --- a/.travis/build-linux.bash +++ b/.travis/build-linux.bash @@ -1,5 +1,5 @@ #!/bin/env bash -ex -DLLPACK_VERSION="190213" +DLLPACK_VERSION="190421" shopt -s nocasematch cd /build/Taiwu_Mods diff --git a/AutoRepair/.modignore b/AutoRepair/.modignore new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/AutoRepair/.modignore @@ -0,0 +1 @@ + diff --git a/BuriedTreasureDetector/.modignore b/BuriedTreasureDetector/.modignore new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/BuriedTreasureDetector/.modignore @@ -0,0 +1 @@ + diff --git a/BuriedTreasureDetector/BuriedTreasureDetector.cs b/BuriedTreasureDetector/BuriedTreasureDetector.cs new file mode 100644 index 0000000..d030135 --- /dev/null +++ b/BuriedTreasureDetector/BuriedTreasureDetector.cs @@ -0,0 +1,320 @@ +using Harmony12; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEngine; +using UnityEngine.UI; +using UnityModManagerNet; +using static UnityModManagerNet.UnityModManager; + +namespace BuriedTreasureDetector +{ + public class Settings : ModSettings + { + public override void Save(ModEntry modEntry) + { + ModSettings.Save(this, modEntry); + } + + /// + /// 掉率精确到小数点后几位 + /// + public int decimalPlace = 4; + /// + /// 是否显示掉率 + /// + public bool isShowProbabilityInMap = false; + /// + /// 是否开启工人自动采集 + /// + public bool workerCanGetTreasure = false; + /// + /// 在地图中显示寻宝奇遇 + /// + public bool isShowStoryInMap = false; + /// + /// 在过月天灾中显示奇遇 + /// + public bool isShowStory = false; + /// + /// 在地块中显示锄地掉率 + /// + public bool isShowProbability = false; + } + + public static class Main + { + public static bool enabled; + public static Settings settings; + public static ModEntry.ModLogger Logger; + + public static bool Load(ModEntry modEntry) + { + Logger = modEntry.Logger; + settings = ModSettings.Load(modEntry); + var harmony = HarmonyInstance.Create(modEntry.Info.Id); + harmony.PatchAll(Assembly.GetExecutingAssembly()); + modEntry.OnToggle = OnToggle; + modEntry.OnGUI = OnGUI; + modEntry.OnSaveGUI = OnSaveGUI; + return true; + } + + static void OnGUI(ModEntry modEntry) + { + GUILayout.BeginHorizontal(); + settings.isShowStory = GUILayout.Toggle(settings.isShowStory, "在过月天灾中显示奇遇", new GUILayoutOption[0]); + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(); + settings.isShowProbability = GUILayout.Toggle(settings.isShowProbability, "在地块中显示锄地掉率及坐标", new GUILayoutOption[0]); + GUILayout.EndHorizontal(); + + + GUILayout.BeginHorizontal(); + settings.isShowStoryInMap = GUILayout.Toggle(settings.isShowStoryInMap, "在地图中显示寻宝奇遇", new GUILayoutOption[0]); + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(); + settings.isShowProbabilityInMap = GUILayout.Toggle(settings.isShowProbabilityInMap, "在地图中显示锄地掉率", new GUILayoutOption[0]); + GUILayout.EndHorizontal(); + GUILayout.BeginHorizontal(); + GUILayout.Label("掉率显示小数点后位数:", GUILayout.Width(150)); + string strDecimalPlace = GUILayout.TextArea(Main.settings.decimalPlace.ToString(), GUILayout.Width(60)); + if (int.TryParse(strDecimalPlace, out int number)) + { + Main.settings.decimalPlace = number; + } + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(); + settings.workerCanGetTreasure = GUILayout.Toggle(settings.workerCanGetTreasure, "开启过月自动采集", new GUILayoutOption[0]); + GUILayout.EndHorizontal(); + } + + public static bool OnToggle(ModEntry modEntry, bool value) + { + enabled = value; + return true; + } + + static void OnSaveGUI(ModEntry modEntry) + { + settings.Save(modEntry); + } + } + + /// + /// Patch: 设置浮窗文字 + /// + [HarmonyPatch(typeof(WindowManage), "WindowSwitch")] + public static class WindowManage_WindowSwitch_Patch + { + public static void Postfix(bool on, GameObject tips, ref int ___tipsW) + { + if (!Main.enabled || ActorMenu.instance == null || tips == null || !on) return; + + string[] array; + int worldId; + int partId; + int placeId; + int mapWidth; + + switch (tips.tag) + { + case "MianPlace": + //地块 + //___informationMassage.text == "\n"; + if (Main.settings.isShowProbability) + { + array = tips.transform.parent.name.Split(','); + partId = array.Length > 2 ? int.Parse(array[2]) : -1; + placeId = array.Length > 3 ? int.Parse(array[3]) : -1; + mapWidth = partId != -1 ? int.Parse(DateFile.instance.partWorldMapDate[partId][98]) : 0; + + //WindowManage.instance.informationName.text += String.Format("({0},{1})", Mathf.FloorToInt(placeId % mapWidth), Mathf.FloorToInt(placeId / mapWidth)); + WindowManage.instance.informationMassage.text += String.Format("位置:({0},{1})", Mathf.FloorToInt(placeId % mapWidth), Mathf.FloorToInt(placeId / mapWidth)); + WindowManage.instance.informationMassage.text += GetTreasureMessageByPlace(partId, placeId, mapWidth); + + } + break; + case "PartWorldButton": + //地区 + if (Main.settings.isShowProbabilityInMap || Main.settings.isShowStoryInMap) + { + array = tips.name.Split(','); + partId = array.Length > 2 ? int.Parse(array[2]) : -1; + placeId = array.Length > 3 ? int.Parse(array[3]) : -1; + mapWidth = partId != -1 ? int.Parse(DateFile.instance.partWorldMapDate[partId][98]) : 0; + if (Main.settings.isShowProbabilityInMap) + { + WindowManage.instance.informationMassage.text += GetTreasureMessageByPlace(partId, 0, mapWidth); + + } + if (Main.settings.isShowStoryInMap) + { + WindowManage.instance.informationMassage.text += GetTreasureMessageByBuried(partId, mapWidth); + } + } + break; + case "TrunEventIcon": + //天灾 + if (Main.settings.isShowStory) + { + array = tips.name.Split(','); + if (((array.Length > 1) ? DateFile.instance.ParseInt(array[1]) : 0) != 256) + { + break; + } + if (array[4] == "0") + { + break; + } + partId = array.Length > 2 ? int.Parse(array[2]) : -1; + mapWidth = partId != -1 ? int.Parse(DateFile.instance.partWorldMapDate[partId][98]) : 0; + WindowManage.instance.informationMassage.text += GetTreasureMessageByBuried(partId, mapWidth, false); + } + break; + } + } + + private static string GetTreasureMessageByBuried(int partId, int mapWidth, bool isInMap = true) + { + + if (FindMe.aowu == null || !FindMe.aowu.ContainsKey(partId)) + { + FindMe.aowu = new Dictionary>>(); + Dictionary> dictionary = FindMe.Getplace(partId, mapWidth * mapWidth); + if (dictionary.Keys.Count > 0) + { + FindMe.aowu.Add(partId, dictionary); + } + } + + string text = ""; + if (!FindMe.aowu.ContainsKey(partId)) + { + text += "此地似乎并无宝藏出现……\n"; + } + else + { + text += "传闻:\n在"; + int num2 = FindMe.aowu[partId].Count; + foreach (int placeId in FindMe.aowu[partId].Keys) + { + num2--; + + text += isInMap ? FindMe.Getplacename(partId, placeId, mapWidth) : FindMe.Getplacename(partId, placeId); + + text += "出现了宝物"; + text += FindMe.Getitemename(FindMe.aowu[partId][placeId][0], FindMe.aowu[partId][placeId][1]); + if (num2 == 0) + { + text += "。\n"; + } + else + { + text += ",\n在"; + } + } + } + return text; + } + + private static string GetTreasureMessageByPlace(int partId, int placeId, int mapWidth) + { + List informationMassageText = new List(); + informationMassageText.Add("\n"); + + Dictionary dic = placeId.Equals(0) ? FindAll.Instance.GetPlace(partId) : FindAll.Instance.GetPlace(partId, placeId); + + foreach (var item in dic) + { + if (item.Value.maxProbability.CompareTo(0) == 0) continue; + + int addColoer = Decimal.ToInt32(Decimal.Floor(item.Value.maxProbability * 900)); + addColoer = Math.Max(addColoer, 0); + addColoer = Math.Min(addColoer, 8); + + string probability = item.Value.maxProbability.ToString("P" + Main.settings.decimalPlace.ToString()); + + informationMassageText.Add(DateFile.instance.SetColoer(20001 + item.Value.maxLevel, item.Key + ":")); + informationMassageText.Add(DateFile.instance.SetColoer(20002 + addColoer, probability)); + + if (!placeId.Equals(0)) continue; + + List placeList = new List(); + bool isWordMax = false; + + foreach (var p in item.Value.placeIdList) + { + placeList.Add(string.Format("({0},{1})", Mathf.FloorToInt(p % mapWidth), Mathf.FloorToInt(p / mapWidth))); + + if (!isWordMax && FindAll.Instance.DictionaryPrace[item.Key].maxProbability.CompareTo(item.Value.maxProbability) == 0) + { + isWordMax = true; + } + } + + if (isWordMax) + { + informationMassageText.Add(DateFile.instance.SetColoer(20010, " * ")); + } + else + { + informationMassageText.Add(" "); + } + + informationMassageText.Add("位置: " + String.Join(" ", placeList.ToArray()) + "\n"); + } + + informationMassageText.Add("\n"); + + return string.Concat(informationMassageText); + } + + } + + /// + /// Patch: 展示过月事件 + /// + [HarmonyPatch(typeof(UIDate), "SetTrunChangeWindow")] + public static class UIDate_SetTrunChangeWindow_OnChangeTurn + { + public static void Prefix() + { + if (!Main.enabled) return; + FindAll.Instance.Clear(); + FindMe.aowu.Clear(); + return; + } + + public static void Postfix() + { + if (!Main.enabled || !Main.settings.workerCanGetTreasure) return; + Work.Instance.ChooseTimeWork(); + return; + } + } + + + /// + /// Patch: 推恩释义 + /// + [HarmonyPatch(typeof(MassageWindow), "EndEvent9013_1")] + public static class MassageWindow_EndEvent9013_1_patch + { + private static void Prefix() + { + if (!Main.enabled || MassageWindow.instance.eventValue == null || MassageWindow.instance.eventValue.Count < 2) return; + + switch (MassageWindow.instance.eventValue[1]) + { + case 1: + FindAll.Instance.Clear(); + break; + } + } + } +} diff --git a/BuriedTreasureDetector/FindAll.cs b/BuriedTreasureDetector/FindAll.cs new file mode 100644 index 0000000..8ef5a7d --- /dev/null +++ b/BuriedTreasureDetector/FindAll.cs @@ -0,0 +1,405 @@ +using Harmony12; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEngine; +using UnityEngine.UI; +using UnityModManagerNet; +using static UnityModManagerNet.UnityModManager; + +namespace BuriedTreasureDetector +{ + public class FindAll + { + //private enum ItemKes + //{ + // UnKnow = 0, + // Food = 1, + // Wood = 2, + // Jade = 3, + // Iron = 4, + // Textile = 5, + // Poison = 6, + // Drug = 7 + //} + + private static FindAll _instance; + private static object _instance_Lock = new object(); + public static FindAll Instance + { + get + { + if (_instance == null) + { + lock (_instance_Lock) + { + if (_instance == null) + { + _instance = new FindAll(); + } + } + + } + return _instance; + } + } + + public Dictionary GetPlace(int partId) + { + if (Find.ContainsKey(partId)) + { + // 取得当前地区信息 + return Find[partId]; + } + else + { + Clear(); + DictionaryPrace = SetNewPrace(); + + //循环所有15个大地图 + for (int baseWorldId = 0; baseWorldId < 15; baseWorldId++) + { + //循环所有地图里面的3个地区 + foreach (int basePartId in DateFile.instance.baseWorldDate[baseWorldId].Keys) + { + //获取当前地区的地图宽度 + int mapWidth = int.Parse(DateFile.instance.partWorldMapDate[basePartId][98]); + //设置当前地区信息 + Find.Add(basePartId, SetPlace(basePartId, mapWidth * mapWidth)); + } + } + + return Find[partId]; + } + } + + public void Clear() + { + Find.Clear(); + DictionaryPrace.Clear(); + } + + /// + /// 45个地区信息汇总 + /// + public Dictionary DictionaryPrace = new Dictionary(); + + public Dictionary GetPlace(int partId, int placeId) + { + Dictionary dictionary = new Dictionary(); + dictionary.Add("食材", new PartItem()); + dictionary.Add("木材", new PartItem()); + dictionary.Add("玉石", new PartItem()); + dictionary.Add("铁石", new PartItem()); + dictionary.Add("织物", new PartItem()); + dictionary.Add("药材", new PartItem()); + dictionary.Add("毒物", new PartItem()); + dictionary.Add("茶酒", new PartItem()); + + + GetPlaceWorkItem(partId, placeId, dictionary); + + return dictionary; + } + + private Dictionary SetNewPrace() + { + Dictionary praceItem = new Dictionary(); + praceItem.Add("食材", new WorldItem()); + praceItem.Add("木材", new WorldItem()); + praceItem.Add("玉石", new WorldItem()); + praceItem.Add("铁石", new WorldItem()); + praceItem.Add("织物", new WorldItem()); + praceItem.Add("药材", new WorldItem()); + praceItem.Add("毒物", new WorldItem()); + praceItem.Add("茶酒", new WorldItem()); + return praceItem; + } + + private Dictionary> Find = new Dictionary>(); + + private Dictionary SetPlace(int partId, int mapSize) + { + Dictionary dictionary = new Dictionary(); + dictionary.Add("食材", new PartItem()); + dictionary.Add("木材", new PartItem()); + dictionary.Add("玉石", new PartItem()); + dictionary.Add("铁石", new PartItem()); + dictionary.Add("织物", new PartItem()); + dictionary.Add("药材", new PartItem()); + dictionary.Add("毒物", new PartItem()); + dictionary.Add("茶酒", new PartItem()); + + //循环所有地块 + for (int placeId = 0; placeId < mapSize; placeId++) + { + GetPlaceWorkItem(partId, placeId, dictionary); + } + return dictionary; + } + + /// + /// copy from GetTimeWorkItem WorldMapSystem + /// 获取锄地概率 + /// + /// + /// + private void GetPlaceWorkItem(int partId, int placeId, Dictionary dictionary) + { + int[] nowResourceAll = DateFile.instance.GetPlaceResource(partId, placeId); + + for (int workTyp = 0; workTyp < 6; workTyp++) + { + //最大资源 + int maxResource = Mathf.Max(int.Parse(DateFile.instance.GetNewMapDate(partId, placeId, workTyp + 1)), 1); + //当前资源 + int nowResource = Mathf.Max(nowResourceAll[workTyp], 0); + + //jmswzyk说 如果低于100就歇歇吧 + //最低升级概率 升级到最高品的概率最大为千分之一 + if (maxResource < 100) + { + continue; + } + //获得物品的概率 + int probability_0 = nowResource * 100 / maxResource - 25; + + //基础地形 + int key = DateFile.instance.ParseInt(DateFile.instance.GetNewMapDate(partId, placeId, 13)); + //可得的基础物品集合 + string[] array = DateFile.instance.timeWorkBootyDate[key][workTyp + 1].Split('|'); + + //没有物品可以获取 再见 + if (array == null || array.Length == 0 || array[0] == "0") + { + continue; + } + + int probability_1 = 100; + //地形类型 + int mapType = DateFile.instance.ParseInt(DateFile.instance.GetNewMapDate(partId, placeId, 83)); + //相邻 + List worldMapNeighbor = DateFile.instance.GetWorldMapNeighbor(partId, placeId); + for (int i = 0; i < worldMapNeighbor.Count; i++) + { + //判断相邻地块是否和本地块一致 + if (DateFile.instance.ParseInt(DateFile.instance.GetNewMapDate(partId, worldMapNeighbor[i], 83)) == mapType) + { + probability_1 += 200; + } + } + //升品概率 + Decimal probability_2 = DateFile.instance.ParseInt(DateFile.instance.timeWorkBootyDate[key][workTyp + 1001]) + Mathf.Max(maxResource - 100, 0) / 10 * probability_1 / 100; + + //提升品级 + int upLevel = DateFile.instance.ParseInt(DateFile.instance.timeWorkBootyDate[key][workTyp + 101]); + Decimal probability_3 = probability_2 * (nowResource * 100 / maxResource) / 100; + + //num6/100 乘 (num8/100 的 num7 次方) + //if (UnityEngine.Random.Range(0, 100) < num6) + //for (int j = 0; j < num7; j++) + //if (UnityEngine.Random.Range(0, 100) < num8) + // 获取最高品的概率 + Decimal probability = (probability_2 / 100) * new Decimal(Math.Pow((Decimal.ToDouble(probability_3) / 100), upLevel)); + + // 最终 挖到东西且获得最高品概率为 + probability = probability / 100 * probability_0; + + //probability = Math.Round(probability, Main.settings.decimalPlace); + + // 获取最高品物品的品级 + int maxLevel = int.Parse(DateFile.instance.GetItemDate(int.Parse(array[0]) + upLevel, 8)); + + // 循环所有可获得的基础物品 + foreach (var strItemId in array) + { + int itemId = int.Parse(strItemId); + string itemName = Getitemename(itemId, workTyp); + + if (itemName.Equals("unknow")) + { + continue; + } + + if (dictionary[itemName].maxProbability.CompareTo(0) == 0) + { + //dictionary[itemName] = new PlaceItem(probability, maxLevel, placeId); + dictionary[itemName].maxProbability = probability; + dictionary[itemName].maxLevel = maxLevel; + dictionary[itemName].placeIdList.Add(placeId); + } + else + { + //该地点以及在字典中 不需要进行判断 + if (dictionary[itemName].placeIdList.Contains(placeId)) + { + continue; + } + try + { + //当前地块概率最大值比较 保存概率大的地块 + int check = probability.CompareTo(dictionary[itemName].maxProbability); + if (check > 0) + { + dictionary[itemName] = new PartItem(probability, maxLevel, placeId); + } + else if (check == 0) + { + dictionary[itemName].placeIdList.Add(placeId); + } + + //当前地块与全世界地块比较 保存概率大的地块 + check = probability.CompareTo(DictionaryPrace[itemName].maxProbability); + if (check > 0) + { + DictionaryPrace[itemName].maxProbability = probability; + DictionaryPrace[itemName].PartPlaceDic.Clear(); + DictionaryPrace[itemName].PartPlaceDic.Add(partId, new List() { placeId }); + } + else if (check == 0) + { + if (DictionaryPrace[itemName].PartPlaceDic.ContainsKey(partId)) + { + //if (!DictionaryPrace[itemName].PartPlaceDic[partId].Contains(placeId)) + //{ + // DictionaryPrace[itemName].PartPlaceDic[partId].Add(placeId); + //} + DictionaryPrace[itemName].PartPlaceDic[partId].Add(placeId); + } + else + { + DictionaryPrace[itemName].PartPlaceDic.Add(partId, new List() { placeId }); + } + } + } + catch (Overflow​Exception e) + { + Main.Logger.Log("==============Overflow​ExceptionS=============="); + + Main.Logger.Log("probability:" + probability.ToString("R")); + Main.Logger.Log("dictionary:" + dictionary[itemName].maxProbability.ToString("R")); + + Main.Logger.Log("probability_1:" + probability_2.ToString()); + Main.Logger.Log("probability_2:" + probability_3.ToString()); + Main.Logger.Log("upLevel:" + upLevel.ToString()); + Main.Logger.Log("==============Overflow​ExceptionE=============="); + } + catch (Exception e) + { + Main.Logger.Log("==============ExceptionS=============="); + Main.Logger.Log("Message:" + e.Message); + Main.Logger.Log("StackTrace:" + e.StackTrace); + + Main.Logger.Log("probability:" + probability.ToString("R")); + Main.Logger.Log("dictionary:" + dictionary[itemName].maxProbability.ToString("R")); + Main.Logger.Log("==============ExceptionE=============="); + } + + } + } + + } + } + + /// + /// 获得物品信息 + /// + /// 物品Id + /// 物品种类Id + /// 物品信息 + public string Getitemename(int storyid, int key) + { + string str; + switch (key) + { + case 0: + str = "食材"; + break; + case 1: + str = "木材"; + break; + case 2: + if (storyid > 3114) + { + str = "玉石"; + } + else + { + str = "铁石"; + } + break; + case 3: + str = "织物"; + break; + case 4: + str = ((storyid > 4096) ? "毒物" : "药材"); + break; + case 5: + str = "茶酒"; + break; + default: + str = "unknow"; + break; + } + return str; + } + } + + /// + /// 世界信息 + /// + public class WorldItem + { + /// + /// 最高掉率 + /// + public Decimal maxProbability = 0; + + /// + /// 地区加地块的ID集合 + /// + public Dictionary> PartPlaceDic; + + public WorldItem() + { + maxProbability = 0; + PartPlaceDic = new Dictionary>(); + } + } + + /// + /// 地区信息 + /// + public class PartItem + { + /// + /// 最高掉率 + /// + public Decimal maxProbability = 0; + + /// + /// 最高物品 + /// + public int maxLevel = 0; + + /// + /// 位置 + /// + public List placeIdList = new List(); + + public PartItem() + { + maxProbability = 0; + maxLevel = 0; + placeIdList = new List(); + } + + public PartItem(Decimal maxProbability, int maxLevel, int placeId) + { + this.maxProbability = maxProbability; + this.maxLevel = maxLevel; + placeIdList = new List() { placeId }; + } + } +} diff --git a/BuriedTreasureDetector/FindMe.cs b/BuriedTreasureDetector/FindMe.cs new file mode 100644 index 0000000..b3fbcc7 --- /dev/null +++ b/BuriedTreasureDetector/FindMe.cs @@ -0,0 +1,119 @@ +using Harmony12; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEngine; +using UnityEngine.UI; +using UnityModManagerNet; +using static UnityModManagerNet.UnityModManager; + +namespace BuriedTreasureDetector +{ + public static class FindMe + { + public static Dictionary> Getplace(int _partId,int mapSize) + { + Dictionary> dictionary = new Dictionary>(); + //循环所有地块 + for (int placeId = 0; placeId < mapSize; placeId++) + { + //如果有奇遇 + if (DateFile.instance.HaveStory(_partId, placeId)) + { + int storyid = DateFile.instance.worldMapState[_partId][placeId][0]; + foreach (int key in FindMe.type.Keys) + { + if (FindMe.type[key].Contains(storyid)) + { + dictionary.Add(placeId, new List + { + storyid, + key + }); + break; + } + } + } + } + return dictionary; + } + + /// + /// 天灾情况下 获得地块信息 + /// + /// + /// + /// + /// 地块信息 + public static string Getplacename(int partId, int placeId) + { + return DateFile.instance.SetColoer(10002, DateFile.instance.GetNewMapDate(partId, placeId, 98) + DateFile.instance.GetNewMapDate(partId, placeId, 0), false); + } + + /// + /// 地区情况下 获得地块信息 + /// + /// 地区ID + /// 地块ID + /// 地区地块总个数 + /// 地块信息 + public static string Getplacename(int partId, int placeId, int num) + { + return DateFile.instance.SetColoer(10002, DateFile.instance.GetNewMapDate(partId, placeId, 0) + placeId % num + "," + placeId / num, false); + } + + /// + /// 获得物品信息 + /// + /// 物品Id + /// 物品种类Id + /// 物品信息 + public static string Getitemename(int storyid, int key) + { + string str = "谜"; + int num = 20009; + switch (key) + { + case 0: + num--; + str = "食材"; + break; + case 1: + str = ((storyid > 3007) ? "软木" : "硬木"); + break; + case 2: + if (storyid > 3207) + { + str = "软玉"; + } + else if (storyid > 3114) + { + str = "硬玉"; + } + else if (storyid > 3107) + { + str = "软铁"; + } + else + { + str = "硬铁"; + } + break; + case 3: + str = ((storyid > 3307) ? "丝布" : "皮革"); + break; + case 4: + str = ((storyid > 4096) ? "毒物" : "药材"); + break; + } + return DateFile.instance.SetColoer(num, DateFile.instance.baseStoryDate[storyid][0].Replace("寻找", "(" + str + ")"), false); + } + + public static Dictionary>> aowu = new Dictionary>>(); + + private static FieldInfo disastersStorys = typeof(PeopleLifeAI).GetField("disastersStorys", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.NonPublic); + + private static Dictionary type = (Dictionary)FindMe.disastersStorys.GetValue(PeopleLifeAI.instance); + } +} diff --git a/BuriedTreasureDetector/Info.json b/BuriedTreasureDetector/Info.json new file mode 100644 index 0000000..f568734 --- /dev/null +++ b/BuriedTreasureDetector/Info.json @@ -0,0 +1,8 @@ +{ + "Id": "BuriedTreasureDetector", + "DisplayName": "寻宝", + "Author": "Eiffel2018/koketsu/jmswzyk/inpayh", + "Version": "1.1.0", + "AssemblyName": "BuriedTreasureDetector.dll", + "EntryMethod": "BuriedTreasureDetector.Main.Load" +} \ No newline at end of file diff --git a/BuriedTreasureDetector/README.md b/BuriedTreasureDetector/README.md new file mode 100644 index 0000000..c48d66e --- /dev/null +++ b/BuriedTreasureDetector/README.md @@ -0,0 +1,12 @@ +## 集合了TreasureDetector寻宝神器 BuriedTreasure寻找天材地宝 2个mod 应该不会和原mod冲突吧? +## BuriedTreasure+TreasureDetector = BuriedTreasureDetector + +# 功能概要 +* 每个地块可显示坐标、及获得最高品物品的概率(需要地块资源上限大于100) +* 地图界面可以看该地区各种物品的掉率及其坐标,如果你发现带了一个星号,说明这是全部45个地区33000个地块里面概率最高的地方。 +* 地图界面可以看该地区的寻宝奇遇(就是天灾带来的那个奇遇)。 +* 自定义掉率显示的位数(精确到小数点后几位)。 +* 提供采集人力自动采集功能(需要当前采集的资源上限大于100且当前资源等同资源上限)。不用天天看地块资源是不是满了过去锄一锄头了(其实我只是觉得SL太累,弄个挂机挂好了)。 +* 地块信息及时更新,地图信息目前仅有过月及其推恩释义的时候会刷新。(获取33000个地块的7种物品信息运行的时间有点长。) +* 太吾锄地及剑冢分身导致地块资源变化不会更新地图上显示的掉率。 +* 应该不会和原来的MOD冲突。有问题了再说。 \ No newline at end of file diff --git a/BuriedTreasureDetector/Work.cs b/BuriedTreasureDetector/Work.cs new file mode 100644 index 0000000..4947ba1 --- /dev/null +++ b/BuriedTreasureDetector/Work.cs @@ -0,0 +1,103 @@ +using Harmony12; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEngine; +using UnityEngine.UI; +using UnityModManagerNet; +using static UnityModManagerNet.UnityModManager; + +namespace BuriedTreasureDetector +{ + public class Work + { + private static Work _instance; + private static object _instance_Lock = new object(); + public static Work Instance + { + get + { + if (_instance == null) + { + lock (_instance_Lock) + { + if (_instance == null) + { + _instance = new Work(); + } + } + + } + return _instance; + } + } + + + public void ChooseTimeWork() + { + //循环所有15个大地图 + for (int baseWorldId = 0; baseWorldId < 15; baseWorldId++) + { + //循环所有地图里面的3个地区 + foreach (int basePartId in DateFile.instance.baseWorldDate[baseWorldId].Keys) + { + // 判断当前地图是否有人力 + //if (DateFile.instance.manpowerUseList.ContainsKey(basePartId)) + if (DateFile.instance.worldMapWorkState.ContainsKey(basePartId)) + { + //获取当前地区的地图宽度 + int mapWidth = int.Parse(DateFile.instance.partWorldMapDate[basePartId][98]); + + //循环所有地块 + for (int placeId = 0; placeId < mapWidth * mapWidth; placeId++) + { + // 判断当前地块是否有人力 + //if (DateFile.instance.manpowerUseList[basePartId].ContainsKey(placeId)) + if (DateFile.instance.worldMapWorkState[basePartId].ContainsKey(placeId)) + { + // 采集类型 + int workTyp = DateFile.instance.worldMapWorkState[basePartId][placeId] - 1; + + //最大资源 + int maxResource = Mathf.Max(int.Parse(DateFile.instance.GetNewMapDate(basePartId, placeId, workTyp + 1)), 1); + //当前资源 + int nowResource = Mathf.Max(DateFile.instance.GetPlaceResource(basePartId, placeId)[workTyp], 0); + + if (maxResource >= 100 && maxResource.Equals(nowResource)) + { + ChooseTimeWork(basePartId, placeId, workTyp); + } + } + } + } + } + } + } + + + private void ChooseTimeWork(int choosePartId, int choosePlaceId, int chooseWorkTyp) + { + int num = DateFile.instance.GetPlaceResource(choosePartId, choosePlaceId)[chooseWorkTyp]; + int num2 = (num >= 100) ? (num * 60 / 100) : (num * 40 / 100); + num2 += UnityEngine.Random.Range(-num2 * 20 / 100, num2 * 20 / 100 + 1); + int getItemId = WorldMapSystem.instance.GetTimeWorkItem(DateFile.instance.MianActorID(), choosePartId, choosePlaceId, chooseWorkTyp, -1, getItem: false, actorWork: true); + int addResource = Mathf.Max(num2, 0); + TimeWorkEnd(addResource, getItemId, choosePartId, choosePlaceId, chooseWorkTyp); + } + private static void TimeWorkEnd(int addResource, int getItemId, int choosePartId, int choosePlaceId, int chooseWorkTyp) + { + // 更新物品 + if (getItemId != 0) + { + DateFile.instance.GetItem(DateFile.instance.MianActorID(), getItemId, 1, true, 0); + } + //更新地块信息 + UIDate.instance.ChangePlaceResource(false, -25, choosePartId, choosePlaceId, chooseWorkTyp); + int num = (DateFile.instance.worldResource == 0) ? 10 : 5; + int num2 = (DateFile.instance.worldResource == 0) ? 4 : 2; + // 更新太吾资源 + UIDate.instance.ChangeResource(DateFile.instance.MianActorID(), chooseWorkTyp, (chooseWorkTyp == 5) ? (addResource * num) : (addResource * num2)); + } + } +} diff --git a/CMakeLists.txt b/CMakeLists.txt index cc7d71d..4946661 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -201,7 +201,7 @@ IF(WIN32) #下载编译用dlls zip包 -set(DLLPACK_VERSION "190213") +set(DLLPACK_VERSION "190421") set(DLLPACK_NAME "dlls") set(DLLPACK_DIR "${CMAKE_CURRENT_BINARY_DIR}\\${DLLPACK_NAME}") set(DLLPACK_URL "https://github.com/phorcys/Taiwu_mods/releases/download/dll${DLLPACK_VERSION}/dlls-${DLLPACK_VERSION}.zip") @@ -356,6 +356,8 @@ using System.Runtime.Versioning\; set_property(TARGET ${moddir} PROPERTY VS_DOTNET_REFERENCE_UnityEngine.UIElementsModule "${DLLPACK_DIR}\\UnityEngine.UIElementsModule.dll") set_property(TARGET ${moddir} PROPERTY VS_DOTNET_REFERENCE_UnityEngine.UIModule "${DLLPACK_DIR}\\UnityEngine.UIModule.dll") set_property(TARGET ${moddir} PROPERTY VS_DOTNET_REFERENCE_DOTween "${DLLPACK_DIR}\\DOTween.dll") + set_property(TARGET ${moddir} PROPERTY VS_DOTNET_REFERENCE_UnityEngine.PhysicsModule "${DLLPACK_DIR}\\UnityEngine.PhysicsModule.dll") + set_property(TARGET ${moddir} PROPERTY VS_DOTNET_REFERENCE_UnityEngine.Physics2DModule "${DLLPACK_DIR}\\UnityEngine.Physics2DModule.dll") #遍历mod目录下dll,加入引用 FILE(GLOB_RECURSE MODDLLFILES ${moddir}/*.dll) diff --git a/GayMax/.modignore b/GayMax/.modignore new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/GayMax/.modignore @@ -0,0 +1 @@ + diff --git a/GuiBaseUI/CreateUI.cs b/GuiBaseUI/CreateUI.cs index 93663e2..da379e4 100644 --- a/GuiBaseUI/CreateUI.cs +++ b/GuiBaseUI/CreateUI.cs @@ -119,7 +119,7 @@ public static GameObject NewCanvas(int sortLayer = int.MinValue) tf4.anchorMin = new Vector2(1, 0); tf4.anchorMax = new Vector2(1, 1); tf4.anchoredPosition = new Vector2(0, 0); - tf4.sizeDelta = new Vector2(20, 0); + tf4.sizeDelta = new Vector2(Main.settings.handWidth, 0); tf4.pivot = new Vector2(1, 1); Image image4 = go4.GetComponent(); image4.sprite = default(Sprite); @@ -157,6 +157,8 @@ public static GameObject NewCanvas(int sortLayer = int.MinValue) scrollRect.verticalScrollbar = scrollbar; scrollRect.verticalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport; scrollRect.verticalScrollbarSpacing = -3; + + Main.hands.Add(new Main.HandData(image4, image6, tf4, tf6)); break; default: break; diff --git a/GuiBaseUI/GuiBaseUI.cs b/GuiBaseUI/GuiBaseUI.cs index 4c9e80a..199dac8 100644 --- a/GuiBaseUI/GuiBaseUI.cs +++ b/GuiBaseUI/GuiBaseUI.cs @@ -25,6 +25,8 @@ public override void Save(UnityModManager.ModEntry modEntry) public float handR = 0.5882353f; public float handG = 0.807843149f; public float handB = 0.8156863f; + + public int handWidth = 20; } public static class Main { @@ -35,6 +37,22 @@ public static class Main public static Settings settings; public static UnityModManager.ModEntry.ModLogger Logger; + public struct HandData + { + public Image bg; + public Image hand; + public RectTransform bgtf; + public RectTransform handtf; + public HandData(Image b,Image h,RectTransform btf, RectTransform htf) + { + bg = b; + hand = h; + bgtf = btf; + handtf = htf; + } + } + public static List hands = new List(); + public static bool Load(UnityModManager.ModEntry modEntry) { @@ -70,25 +88,109 @@ static void OnSaveGUI(UnityModManager.ModEntry modEntry) } static void OnGUI(UnityModManager.ModEntry modEntry) { + float bgR; + float bgG; + float bgB; + + float handR; + float handG; + float handB; + + + int handWidth; + + GUILayout.Label(title, GUILayout.Width(300)); GUILayout.BeginHorizontal(); GUILayout.Label(string.Format("■■■■■■■■底色" , (Main.settings.bgR * 255 > 16 ? "" : "0") + Convert.ToString((int)(Main.settings.bgR * 255), 16) , (Main.settings.bgG * 255 > 16 ? "" : "0") + Convert.ToString((int)(Main.settings.bgG * 255), 16) , (Main.settings.bgB * 255 > 16 ? "" : "0") + Convert.ToString((int)(Main.settings.bgB * 255), 16))); - Main.settings.bgR = GUILayout.HorizontalSlider(Main.settings.bgR, 0, 1); GUILayout.Label("R:" + (Main.settings.bgR * 255).ToString("000").ToUpper()); - Main.settings.bgG = GUILayout.HorizontalSlider(Main.settings.bgG, 0, 1); GUILayout.Label("G:" + (Main.settings.bgG * 255).ToString("000").ToUpper()); - Main.settings.bgB = GUILayout.HorizontalSlider(Main.settings.bgB, 0, 1); GUILayout.Label("B:" + (Main.settings.bgB * 255).ToString("000").ToUpper()); + bgR = GUILayout.HorizontalSlider(Main.settings.bgR, 0, 1); GUILayout.Label("R:" + (Main.settings.bgR * 255).ToString("000").ToUpper()); + bgG = GUILayout.HorizontalSlider(Main.settings.bgG, 0, 1); GUILayout.Label("G:" + (Main.settings.bgG * 255).ToString("000").ToUpper()); + bgB = GUILayout.HorizontalSlider(Main.settings.bgB, 0, 1); GUILayout.Label("B:" + (Main.settings.bgB * 255).ToString("000").ToUpper()); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label(string.Format("■■■■■■■■前色" , (Main.settings.handR * 255 > 16 ? "" : "0") + Convert.ToString((int)(Main.settings.handR * 255), 16) , (Main.settings.handG * 255 > 16 ? "" : "0") + Convert.ToString((int)(Main.settings.handG * 255), 16) , (Main.settings.handB * 255 > 16 ? "" : "0") + Convert.ToString((int)(Main.settings.handB * 255), 16))); - Main.settings.handR = GUILayout.HorizontalSlider(Main.settings.handR, 0, 1); GUILayout.Label("R:" + (Main.settings.handR * 255).ToString("000").ToUpper()); - Main.settings.handG = GUILayout.HorizontalSlider(Main.settings.handG, 0, 1); GUILayout.Label("G:" + (Main.settings.handG * 255).ToString("000").ToUpper()); - Main.settings.handB = GUILayout.HorizontalSlider(Main.settings.handB, 0, 1); GUILayout.Label("B:" + (Main.settings.handB * 255).ToString("000").ToUpper()); + handR = GUILayout.HorizontalSlider(Main.settings.handR, 0, 1); GUILayout.Label("R:" + (Main.settings.handR * 255).ToString("000").ToUpper()); + handG = GUILayout.HorizontalSlider(Main.settings.handG, 0, 1); GUILayout.Label("G:" + (Main.settings.handG * 255).ToString("000").ToUpper()); + handB = GUILayout.HorizontalSlider(Main.settings.handB, 0, 1); GUILayout.Label("B:" + (Main.settings.handB * 255).ToString("000").ToUpper()); GUILayout.EndHorizontal(); + GUILayout.BeginHorizontal(); + GUILayout.Label(string.Format("设置滑动条宽度{0}", Main.settings.handWidth)); + handWidth = (int)GUILayout.HorizontalSlider(Main.settings.handWidth, 5, 30); + GUILayout.Space(100); + if (GUILayout.Button("使用鬼的配色")) + { + bgR = 0.9490196f; + bgG = 0.509803951f; + bgB = 0.503921571f; + + handR = 0.5882353f; + handG = 0.807843149f; + handB = 0.8156863f; + + handWidth = 20; + } + GUILayout.Space(100); + if (GUILayout.Button("使用太吾配色")) + { + bgR = 0.164705882f; + bgG = 0.164705882f; + bgB = 0.164705882f; + + handR = 0.282352941f; + handG = 0.094117647f; + handB = 0.094117647f; + + handWidth = 10; + } + GUILayout.Space(100); + GUILayout.EndHorizontal(); + + + if ( + Main.settings.bgR != bgR || + Main.settings.bgG != bgG || + Main.settings.bgB != bgB || + Main.settings.handR != handR || + Main.settings.handG != handG || + Main.settings.handB != handB || + Main.settings.handWidth != handWidth + ) + { + Main.settings.bgR = bgR; + Main.settings.bgG = bgG; + Main.settings.bgB = bgB; + Main.settings.handR = handR; + Main.settings.handG = handG; + Main.settings.handB = handB; + Main.settings.handWidth = handWidth; + + List res = new List(); + foreach (var item in hands) + { + if (item.bg == null || item.hand == null || item.bgtf == null || item.handtf == null) + { + res.Add(item); + } + else + { + item.bg.color = new Color(bgR, bgG, bgB); + item.hand.color = new Color(handR, handG, handB); + item.bgtf.sizeDelta = new Vector2(handWidth, 0); + item.handtf.sizeDelta = new Vector2(20, 20); + } + } + foreach (var item in res) + { + hands.Remove(item); + } + } + } @@ -100,7 +202,7 @@ public static void LogAllChild(Transform tf, bool logSize = false, int idx = 0) { s += "-- "; } - s += tf.name; + s += tf.name + " "+tf.gameObject.activeSelf; if (logSize) { RectTransform rect = tf as RectTransform; @@ -113,7 +215,7 @@ public static void LogAllChild(Transform tf, bool logSize = false, int idx = 0) s += " sizeDelta=" + rect.sizeDelta.ToString(); } } - // Main.Logger.Log(s); + Main.Logger.Log(s); idx++; for (int i = 0; i < tf.childCount; i++) diff --git a/GuiBaseUI/IconMove.cs b/GuiBaseUI/IconMove.cs new file mode 100644 index 0000000..4971a59 --- /dev/null +++ b/GuiBaseUI/IconMove.cs @@ -0,0 +1,69 @@ +using DG.Tweening; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; +namespace GuiBaseUI +{ + public class IconMove + { + static Transform root; + static GameObject prefab; + static List pool = new List(); + + public static void Move(Vector3 start, Vector3 target, float duration = .5f, Sprite sprite = null) + { + IconItem item; + if (pool.Count > 0) + { + item = pool[0]; + pool.RemoveAt(0); + } + else + { + item = GetNewIcon(); + } + item.image.sprite = sprite; + item.transform.localScale = Vector3.one; + item.transform.position = start; + var tweener = item.transform.DOMove(target, duration); + tweener.SetEase(Ease.Linear); + tweener.onComplete = delegate () { + if (item.transform) + { + item.transform.localScale = Vector3.zero; + pool.Add(item); + } + }; + } + + static IconItem GetNewIcon() + { + if (root == null) + { + GameObject go = new GameObject(); + go.name = "IconMove"; + root = go.transform; + root.SetParent(Object.FindObjectOfType().transform,false); + root.position = Vector3.zero; + prefab = CreateUI.NewImage(); + prefab.transform.SetParent(root); + prefab.transform.localScale = Vector3.zero; + } + IconItem item = new IconItem(Object.Instantiate(prefab)); + return item; + } + + struct IconItem + { + public Transform transform; + public Image image; + public IconItem(GameObject go) + { + transform = go.transform; + image = go.GetComponent(); + transform.SetParent(root); + transform.localScale = Vector3.zero; + } + } + } +} \ No newline at end of file diff --git a/GuiBaseUI/Info.json b/GuiBaseUI/Info.json index 6244990..ab8006f 100644 --- a/GuiBaseUI/Info.json +++ b/GuiBaseUI/Info.json @@ -1,7 +1,7 @@ { "Id": "GuiBaseUI", - "DisplayName": "鬼的UI 大数据无限滚动", - "Version": "1.3.1", + "DisplayName": "鬼的UI框架", + "Version": "2.2", "AssemblyName": "GuiBaseUI.dll", "EntryMethod": "GuiBaseUI.Main.Load" } \ No newline at end of file diff --git a/GuiConsultModestly/.modignore b/GuiConsultModestly/.modignore new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/GuiConsultModestly/.modignore @@ -0,0 +1 @@ + diff --git a/GuiConsultModestly/GuiConsultModestly.cs b/GuiConsultModestly/GuiConsultModestly.cs new file mode 100644 index 0000000..add0f3b --- /dev/null +++ b/GuiConsultModestly/GuiConsultModestly.cs @@ -0,0 +1,600 @@ +using Harmony12; +using System; +using System.Collections.Generic; +using System.Reflection; +using UnityEngine; +using UnityEngine.UI; +using UnityModManagerNet; +using System.Text.RegularExpressions; +using System.Linq; +using System.Reflection.Emit; +using System.Text; + +namespace GuiConsultModestly +{ + public class Settings : UnityModManager.ModSettings + { + public int AddWind = 0; + public int ReadLevel = 1; + public override void Save(UnityModManager.ModEntry modEntry) + { + UnityModManager.ModSettings.Save(this, modEntry); + } + + } + public static class Main + { + public static bool enabled; + public static Settings settings; + public static UnityModManager.ModEntry.ModLogger Logger; + + + public static bool Load(UnityModManager.ModEntry modEntry) + { + #region 基础设置 + settings = Settings.Load(modEntry); + Logger = modEntry.Logger; + modEntry.OnToggle = OnToggle; + modEntry.OnGUI = OnGUI; + modEntry.OnSaveGUI = OnSaveGUI; + + HarmonyInstance harmony = HarmonyInstance.Create(modEntry.Info.Id); + harmony.PatchAll(Assembly.GetExecutingAssembly()); + #endregion + + return true; + } + + static string title = "鬼的虚心请教"; + public static bool OnToggle(UnityModManager.ModEntry modEntry, bool value) + { + enabled = value; + return true; + } + static void OnSaveGUI(UnityModManager.ModEntry modEntry) + { + settings.Save(modEntry); + } + static void OnGUI(UnityModManager.ModEntry modEntry) + { + GUILayout.Label(title, GUILayout.Width(300)); + + GUILayout.BeginHorizontal(); + Main.settings.AddWind = (int)GUILayout.HorizontalSlider(Main.settings.AddWind, 0, 30); + GUILayout.Label(string.Format("作弊增加成功率:{0}%", Main.settings.AddWind)); + float v = Main.settings.AddWind / 100f; + GUILayout.Label(" 16 ? "" : "0") + Convert.ToString((int)(v * 255), 16) + "0000>此举有伤天和,请酌情使用"); + GUILayout.EndHorizontal(); + GUILayout.BeginHorizontal(); + Main.settings.ReadLevel = (int)GUILayout.HorizontalSlider(Main.settings.ReadLevel, 1, 3); + GUILayout.Label(string.Format("作弊增加研读页数:{0}倍", Main.settings.ReadLevel)); + v = (Main.settings.ReadLevel - 1) / 9f; + GUILayout.Label(" 16 ? "" : "0") + Convert.ToString((int)(v * 255), 16) + "0000>此举有伤天和,请酌情使用"); + GUILayout.EndHorizontal(); + } + + [HarmonyPatch(typeof(SkillBattleSystem), "AnQusetion")] + public static class SkillBattleSystem_AnQusetion_Patch + { + static FieldInfo m_actorSkillBattleValue; + public static int[] actorSkillBattleValue + { + get + { + //if (m_actorSkillBattleValue == null) + //{ + m_actorSkillBattleValue = typeof(SkillBattleSystem).GetField("actorSkillBattleValue", BindingFlags.NonPublic | BindingFlags.Instance); + //} + int[] value; + try + { + value = (int[])m_actorSkillBattleValue.GetValue(SkillBattleSystem.instance); + } + catch + { + value = new int[9]; + Main.Logger.Log("反射出错"); + } + + return value; + } + } + static FieldInfo m_enemySkillBattleValue; + public static int[] enemySkillBattleValue + { + get + { + //if (m_enemySkillBattleValue == null) + //{ + m_enemySkillBattleValue = typeof(SkillBattleSystem).GetField("enemySkillBattleValue", BindingFlags.NonPublic | BindingFlags.Instance); + //} + int[] value; + try + { + value = (int[])m_enemySkillBattleValue.GetValue(SkillBattleSystem.instance); + } + catch + { + value = new int[9]; + Main.Logger.Log("反射出错"); + } + + return value; + } + } + + static FieldInfo m_nowSkillIndex; + public static int nowSkillIndex + { + get + { + //if (m_nowSkillIndex == null) + //{ + m_nowSkillIndex = typeof(SkillBattleSystem).GetField("nowSkillIndex", BindingFlags.NonPublic | BindingFlags.Instance); + //} + int value; + try + { + value = (int)m_nowSkillIndex.GetValue(SkillBattleSystem.instance); + } + catch + { + value = 0; + Main.Logger.Log("反射出错"); + } + + return value; + } + } + static FieldInfo m_questionPower; + public static int questionPower + { + get + { + //if (m_questionPower == null) + //{ + m_questionPower = typeof(SkillBattleSystem).GetField("questionPower", BindingFlags.NonPublic | BindingFlags.Instance); + //} + int value; + try + { + value = (int)m_questionPower.GetValue(SkillBattleSystem.instance); + } + catch + { + value = 0; + Main.Logger.Log("反射出错"); + } + + return value; + } + } + static FieldInfo m_mianEnemyId; + public static int mianEnemyId + { + get + { + //if (m_mianEnemyId == null) + //{ + m_mianEnemyId = typeof(SkillBattleSystem).GetField("mianEnemyId", BindingFlags.NonPublic | BindingFlags.Instance); + //} + int value; + try + { + value = (int)m_mianEnemyId.GetValue(SkillBattleSystem.instance); + } + catch + { + value = 0; + Main.Logger.Log("反射出错"); + } + + return value; + } + } + static SkillBattleSystem _this = SkillBattleSystem.instance; + static void Postfix(bool isActor) + { + if (!Main.enabled) + return; + _this = SkillBattleSystem.instance; + + try + { + string[] conten = SetSkillBatterGains(isActor); + if (conten != null && conten[0] != null) + { + YesOrNoWindow.instance.SetYesOrNoWindow(-1, conten[0], conten[1], false, true); + } + } + catch (Exception e) + { + YesOrNoWindow.instance.SetYesOrNoWindow(-1, "鬼的虚心请教 MOD出错", e.Message, false, true); + } + } + + /// + /// 设置技艺比拼收获 + /// + static string[] SetSkillBatterGains(bool isActor) + { + Main.Logger.Log("设置技艺比拼收获"); + if (isActor) + return null; + + + string[] result = new string[2]; + int typ = nowSkillIndex; + int power = questionPower; + int battleValue = 0; + int opponentBattleValue = 0; + string selfName = ""; + string opponentName = ""; + int _actorId = DateFile.instance.MianActorID(); + int _mianEnemyId = mianEnemyId; + + battleValue = actorSkillBattleValue[typ]; + opponentBattleValue = enemySkillBattleValue[typ]; + selfName = "" + DateFile.instance.GetActorName(_actorId, false, false) + ""; + opponentName = "" + DateFile.instance.GetActorName(_mianEnemyId, false, false) + ""; + + //int _skillId = DateFile.instance.ParseInt(DateFile.instance.baseSkillDate[_this.battleSkillTyp][typ + 1]); + int _skillId = int.Parse(DateFile.instance.baseSkillDate[_this.battleSkillTyp][typ + 1], System.Globalization.CultureInfo.InvariantCulture); + //string book_name = DateFile.instance.skillDate[_skillId][typ];// 书籍名 + var data = DateFile.instance.skillDate[int.Parse(DateFile.instance.baseSkillDate[_this.battleSkillTyp][nowSkillIndex + 1], System.Globalization.CultureInfo.InvariantCulture)]; + string book_name = "《" + data[0] + "》" + data[1001]; + string bname = "《" + data[0] + "》"; + + + + int value = 0; + int num = 0;// 上一阶书籍读的页数 + int num2 = 0;// 当前阶书籍读的页数 + + // 判断是否一阶书籍 + int stage = int.Parse(data[2]); + + // 计算当前阶书籍读了几页 + bool flagB = DateFile.instance.skillBookPages.ContainsKey(_skillId); + if (flagB) + { + for (int pageIndex = 0; pageIndex < 10; pageIndex++) + { + int num8 = DateFile.instance.skillBookPages[_skillId][pageIndex]; + bool flag9 = num8 == 1; + if (flag9) + { + num2++; + } + } + } + + // 计算上一阶书籍读了几页 + bool flagC = DateFile.instance.skillBookPages.ContainsKey(_skillId - 1); + if (flagC) + { + for (int pageIndex = 0; pageIndex < 10; pageIndex++) + { + int num8 = DateFile.instance.skillBookPages[_skillId - 1][pageIndex]; + bool flag9 = num8 == 1; + if (flag9) + { + num++; + } + } + } + + // (当前比拼是第一阶 或者 上一阶书已读满五页)并且当前比拼的书籍尚未读满10页 + if (num2 != 10 && (stage == 1 || num >= 5)) + { + int exceed = power - battleValue; + if (exceed < 1) + { + if (opponentBattleValue > (battleValue + 100)) // 深刻理解:虽然《"+book_name+"》已经熟读于心,但是听了"+opponentName+"的讲解之后,有了更深刻的认识。 + { + result[0] = "理解加深"; + result[1] = "虽然" + selfName + "已然知晓" + book_name + ",但是听了" + opponentName + "的讲解之后,有了更深刻的认识。"; + value = 20; + } + else if (battleValue > (opponentBattleValue + 100)) // 指点江山:《"+book_name+"》心中已经有了深刻认识,觉得"+opponentName+"讲解颇有不足,为其讲解了此中深意。 + { + result[0] = "指点江山"; + result[1] = selfName + "觉得" + opponentName + "对" + book_name + "理解不够深刻,为其讲解了此中深意," + opponentName + "感激不尽。\n【需要对方水平比自己高100】"+ + opponentBattleValue +":"+ battleValue + ""; + } + else + { + result[0] = "各抒己见"; + result[1] = selfName + "和" + opponentName + "对" + book_name + "均有不同见解,双方吵得不可开交,差点就打起来了\n【需要对方水平比自己高100】" + + opponentBattleValue + ":" + battleValue + ""; + } + } + else if (exceed >= 1 && exceed <= 100) // 茅塞顿开:《"+book_name+"》已经困扰自己已久,此时听了"+opponentName+"的讲解之后茅塞顿开,心中有了更深刻的认识。 + { + result[0] = "茅塞顿开"; + result[1] = book_name + "中的内容已经困扰" + selfName + "已久,此时听了" + opponentName + "的讲解之后茅塞顿开,对" + book_name + "有了更深刻的认识。"; + value = 90; + } + else if (exceed >= 101 && exceed <= 200) // 一知半解:听了"+opponentName+"讲解受益良多,但《"+book_name+"》颇有难度,心中仍有多处不解。 + { + result[0] = "受益良多"; + result[1] = selfName + "听了" + opponentName + "讲解受益良多,但" + book_name + "颇有难度,心中多处不解变得明朗起来。"; + value = 40; + } + else if (exceed >= 201) // 一头雾水:听着"+opponentName+"滔滔不绝指点江山,心中毫无头绪,对《"+book_name+"》完全无法理解。 + { + result[0] = "一头雾水"; + result[1] = selfName + "听着" + opponentName + "滔滔不绝指点江山,心中毫无头绪,对" + book_name + "始终无法理解。"; + } + + if (value > 0) + { + var seven = ActorMenu.instance.GetActorResources(_actorId)[0]; // 七元赋性: 0 = 细腻 1 = 聪颖 2 = 水性 3 = 勇壮 4 = 坚毅 5 = 冷静 6 = 机缘 + var rand = UnityEngine.Random.Range(0, 100); + var need = (value + seven + Main.settings.AddWind); + result[1] += "\n【细腻影响领悟成功率】粗心点数越小越好" + rand + "/" + need+ ""; + value = rand <= need ? 1 : 0; + + if (value > 0) + { + seven = ActorMenu.instance.GetActorResources(_actorId)[1]; + rand = UnityEngine.Random.Range(0, 95) + seven + Main.settings.AddWind; // 七元赋性: 0 = 细腻 1 = 聪颖 2 = 水性 3 = 勇壮 4 = 坚毅 5 = 冷静 6 = 机缘 + need = (stage * 10); + result[1] += "\n【聪颖影响研读成功率】研读点数越大越好" + rand + "/" + need + ""; + //Logger.Log(stage + "阶书籍判断几率 " + rand + "<=" + (stage * 10) + " " + (rand <= (stage * 10))); + if (rand <= need) // 书籍阶数 研读成功率越低 + value = 0; + } + + if (value > 0) + { + //Logger.Log(stage + "阶书籍 下级将研读 " + (num2+1) + "<=" + (power / 90) + " 问题难度 " + power + " " + (num2 > (power / 90))); + //Logger.Log(stage + "阶书籍 下级将研读 " + (num2+1) + "<=" + (power / 90) + " 问题难度 " + power + " " + (num2 > (power / 90))); + if ((num2*90) > power) + { + value = 0; + result[1] += "\n【书籍页数相关】题目难度不足" + power + "/" + (num2 * 90)+ ""; + } + } + + if (value > 0 && result[0] == "受益良多" && (num2 + 1) <= (power / 90)) + { + value = 2; + } + + + // 如果大于0则增加技艺等级 + if (value > 0) + { + value = value * Main.settings.ReadLevel; + value = SkillFLevel(_skillId, value); + } + } + + if (value > 0) + { + result[1] += "\n\n\n【" + selfName + "抓住了一丝明悟," + book_name + "研习进度增加了" + value + "页】"; + } + else if(value != -100) + { + int rand = UnityEngine.Random.Range(0, 4); + switch (rand) + { + case 1: + result[1] += "\n\n\n【" + selfName + "差点就抓住了那一丝明悟,却没有把握住机会,可惜。】"; + break; + case 2: + result[1] += "\n\n\n【" + opponentName + "有意隐瞒了" + book_name + "的诀窍," + selfName + "虽有所思却没有收获。】"; + break; + case 3: + result[1] += "\n\n\n【" + selfName + "陷入了顿悟之中,却被" + opponentName + "催促赶紧继续比拼而被打断。】"; + break; + default: + result[1] += "\n\n\n【" + selfName + "似乎抓住了一丝明悟,但却不甚明朗,始终无法突破。】"; + break; + } + } + else + { + result[0] = "领悟技艺"; + result[1] = selfName + "在比拼中有所领悟,赶紧将心中领悟记下" + "\n\n\n【获得残页书籍" + bname + "】"; + } + } + else + { + if (num2 == 10) + { + if (opponentBattleValue > (battleValue + 100)) // 深刻理解:虽然《"+book_name+"》已经熟读于心,但是听了"+opponentName+"的讲解之后,有了更深刻的认识。 + { + result[0] = "浅尝辄止"; + result[1] = selfName + "已读过" + book_name + ",断断续续答上了" + opponentName + "的问题,运用了一些伎俩避过了一些刁钻的问题。"; + } + else if (battleValue > (opponentBattleValue + 100)) // 指点江山:《"+book_name+"》心中已经有了深刻认识,觉得"+opponentName+"讲解颇有不足,为其讲解了此中深意。 + { + result[0] = "对答如流"; + result[1] = selfName + "已然熟读" + book_name + "," + opponentName + "听了" + selfName + "的讲解之后频频点头。"; + } + else + { + result[0] = "谈笑风生"; + result[1] = selfName + "与" + opponentName + "对答如流,谈笑风生,都对" + book_name + "有着深刻的认识。"; + } + } + else if (num < 5) + { + result[0] = "一窍不通"; + result[1] = selfName + "听着" + opponentName + "出口成章,侃侃而谈,但" + book_name + "太过高深,完全不知道讲的是啥。"; + } + else + { + result[0] = "相谈甚欢"; + result[1] = selfName + "与" + opponentName + "对" + book_name + "达成一致看法,相谈甚欢。"; + } + //if (num2 != 10 && (stage == 1 || num >= 5)) + if(num2 == 10) + { + result[1]+= "【书籍研习进度已满】"; + }else if(!(stage == 1 || num >= 5)) + { + result[1] += "【需要"+ + DateFile.instance.skillDate[int.Parse(DateFile.instance.baseSkillDate[_this.battleSkillTyp][nowSkillIndex], System.Globalization.CultureInfo.InvariantCulture)][0] + + "研习至5页以上】"; + } + } + + + #region 打印能力值 + + ////// 打印能力值 + //Logger.Log("书页判断结果: " + stage + " " + num + " " + num2); + //string de = "actorSkillBattleValue:"; + //foreach (var item in actorSkillBattleValue) + //{ + // de += " " + item + " "; + //} + //Logger.Log(de); + + //de = "enemySkillBattleValue:"; + //foreach (var item in enemySkillBattleValue) + //{ + // de += " " + item + " "; + //} + //Logger.Log(de); + + //de = _skillId + " actorSkills:"; + //bool flag = DateFile.instance.actorSkills.ContainsKey(_skillId); + //if (flag) + //{ + // var vvv = DateFile.instance.actorSkills[_skillId]; + // foreach (var item in vvv) + // { + // de += " " + item + " "; + // } + // Logger.Log(de); + //} + + //de = _skillId + " skillBookPages:"; + //bool flag3 = DateFile.instance.skillBookPages.ContainsKey(_skillId); + //if (flag3) + //{ + // var vvv = DateFile.instance.skillBookPages[_skillId]; + // foreach (var item in vvv) + // { + // de += " " + item + " "; + // } + // Logger.Log(de); + //} + + //de = _skillId + " skillDate:"; + //bool flag4 = DateFile.instance.skillDate.ContainsKey(_skillId); + //if (flag4) + //{ + // var vvv = DateFile.instance.skillDate[_skillId]; + // foreach (var item in vvv) + // { + // de += " " + item.Key + "=" + item.Value + " "; + // } + // Logger.Log(de); + //} + + //// 打印七元赋性 + //var seven = ActorMenu.instance.GetActorResources(_actorId); + //de = " 七元赋性:"; + //for (int i = 0; i < 7; i++) + //{ + // de += " " + i + "=" + seven[i] + " "; + //} + //Logger.Log(de); + + #endregion + return result; + } + + // 提升技艺研读 + static int SkillFLevel(int skillId, int value) + { + bool flag8 = !DateFile.instance.skillBookPages.ContainsKey(skillId); + if (flag8) + { + // 习得新的书籍 + DateFile.instance.skillBookPages.Add(skillId, new int[10]); + + AddSkillBook(skillId); + return -100; + } + if (value > 0) + { + int[] pages = new int[value]; + int idx = 0; + for (int i = 0; i < 10; i++) + { + if (DateFile.instance.skillBookPages[skillId][i] == 0 && idx < value) + { + pages[idx++] = i; + } + } + + foreach (var pageIndex in pages) + { + int num8 = DateFile.instance.skillBookPages[skillId][pageIndex]; + bool flag9 = num8 != 1 && num8 > -100; + if (flag9) + { + int num9 = int.Parse(DateFile.instance.skillDate[skillId][2], System.Globalization.CultureInfo.InvariantCulture); + bool flag10 = !DateFile.instance.actorSkills.ContainsKey(skillId); + if (flag10) + { + DateFile.instance.ChangeMianSkill(skillId, 0, 0, true); + } + DateFile.instance.skillBookPages[skillId][pageIndex] = 1; + DateFile.instance.AddActorScore(203, num9 * 100); + bool flag11 = DateFile.instance.GetSkillLevel(skillId) >= 100 && DateFile.instance.GetSkillFLevel(skillId) >= 10; + if (flag11) + { + DateFile.instance.AddActorScore(204, num9 * 100); + } + } + } + return idx; + } + return 0; + } + + // 提升技艺修习 + static int SkillLevel(int skillId, int value) + { + + int idx = 0; + return idx; + } + } + + + static void AddSkillBook(int skillId) + { + int itemId = 0; + foreach (var item in DateFile.instance.presetitemDate) + { + if (item.Value.ContainsKey(32)) + { + if (int.Parse(item.Value[32]) == skillId) // 32 是对应的功法 35是是否手抄 + { + itemId = item.Key; + break; + } + } + } + + if (itemId > 0) + { + int item = DateFile.instance.GetItem(DateFile.instance.MianActorID(), itemId, 1, true); + if (item > 0) + { + DateFile.instance.itemsDate[item][33] = "0|0|0|0|0|0|0|0|0|0"; + DateFile.instance.itemsDate[item][901] = "3"; + DateFile.instance.itemsDate[item][902] = "3"; + } + } + } + } +} \ No newline at end of file diff --git a/GuiConsultModestly/Info.json b/GuiConsultModestly/Info.json new file mode 100644 index 0000000..defd419 --- /dev/null +++ b/GuiConsultModestly/Info.json @@ -0,0 +1,7 @@ +{ + "Id": "GuiConsultModestly", + "DisplayName": "鬼的谦虚请教", + "Version": "2.1.0", + "AssemblyName": "GuiConsultModestly.dll", + "EntryMethod": "GuiConsultModestly.Main.Load" +} \ No newline at end of file diff --git a/GuiConsultModestly/Readme.md b/GuiConsultModestly/Readme.md new file mode 100644 index 0000000..865f83e --- /dev/null +++ b/GuiConsultModestly/Readme.md @@ -0,0 +1,67 @@ +鬼的谦虚请教 + +1.0.0 +与对手进行技艺比拼时,如果提出的问题被对手正确解答后有机会可获得获得书籍研习进度。 + 当前对答书页未读满10页 并且前一阶书读满5页以上,可获得以下奖励: + 题目难度低于自身水平 , + 对方能力比自己高较多,理解加深:有机会获得1页书籍研读 + 对方能力比自己低较多,指点江山:觉得对方理解太过疏浅,指点了对方一番 + 双方能力相差无几,各抒己见:双方都认为自己的理解更为深刻 + 题目难度略微超出自身水平 ,对方成功解答,茅塞顿开:听了对方讲解有所明悟,有机会获得1-3页书籍研读。 + 题目难度小幅超出自身水平 ,对方成功解答 ,一知半解:听了对方虽不甚理解但也有所收获,有机会获得1-2页书籍研读。 + 题目难度大幅超出自身水平 ,对方成功解答 ,一头雾水,看对方讲解得高深莫测,头头是道,但是自己却依然无法理解! + 当前书页已经读满10页 + 对方能力比自己高,浅尝辄止:断断续续勉强答上了对方的问题,运用了一些伎俩避过了一些刁钻的问题。 + 对方能力比自己低,对答如流:依然熟读本书,对方听后频频点头。 + 双方能力能力相差无几,谈笑风生:与对方对答如流,谈笑风生,但是没有收获。 + 前一阶书籍尚未读满5页 一窍不通:书中此篇太难了,虽然知道对方说的是对的但是完全无法理解。 + + 当前比拼的书籍品阶越高,越难从比拼中获得书籍研读进度。 + 聪颖越高,越容易从比拼中获得书籍研读进度。 + +1.1.0 + 调整了获得书籍研习的概率 + 理解加深:有较小机会获得1页书籍研读 + 一知半解:有中等机会获得1页书籍研读 + 茅塞顿开:有较大机会获得1页书籍研读 + 降低了所有品阶书籍获得书籍研读的机会 + 降低了聪颖对研读成功率的加成 + +1.2.0 + 修复一个BUG:这个bug导致没有计算书籍品阶和聪颖对成功率的影响 + + 优化mod平衡性: + “一知半解”更名为“受益良多” + 提高了获得书籍研读概率 + 理解加深:15%增加到20% + 受益良多:30%增加到40% 从原本的研读成功增加1页提升到2页(若题目难度不足则依然只能研读1页) + 茅塞顿开:45%增加到90% + 书籍品阶和聪颖分别影响研读成功的概率 + 九品至一品研读成功率调整至:89.47% 78.94% 68.42% 57.89% 47.36% 36.84% 26.31% 15.78% 5.26% + 恢复1.0版本聪颖对研读成功率的加成:每1点聪颖增加1%额外概率 + 增加研读书页对题目难度的要求,第1页至第9页分别要求题目难度:90 180 270 360 450 540 630 720 810 900 + 每次对方解答时如果符合条件会进行两次判断,第一次判断是否获得书籍研读,第二次判断是否研读成功。 + + 增加研读失败提示的语言多样化 + 并不是所有的研读失败都会有弹窗了(取消了80%的研读失败弹窗!) + + + + + + + + + + + +对方能力比自己高较多是场差+100 +对方能力比自己低较多是相差-100 +双方能力相差无几是相差在100以内 + +题目难度略微超出自身水平是超出1-100 +题目难度小幅超出自身水平是超出101-200 +题目难度大幅超出自身水平是超出200以上 + +有机会获得1-x页书籍研读 +研读成功计算: 如果 (Random(10,110) + 聪颖) > ((10-书籍品级)*10) 可获得 Random(0,x+1) 页的书籍研读。 0页也是研读失败 \ No newline at end of file diff --git a/GuiHandle/.modignore b/GuiHandle/.modignore new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/GuiHandle/.modignore @@ -0,0 +1 @@ + diff --git a/GuiHandle/CalculationScreenPosition.cs b/GuiHandle/CalculationScreenPosition.cs new file mode 100644 index 0000000..770f377 --- /dev/null +++ b/GuiHandle/CalculationScreenPosition.cs @@ -0,0 +1,49 @@ +using UnityEngine; + +namespace GuiHandle +{ + public class CalculationScreenPosition : MonoBehaviour + { + // 屏幕坐标与窗口坐标偏移量 + Vector2 offect; + /// + /// 计算屏幕位置 + /// + private void Start() + { + // 设置鼠标位置到游戏窗口中心 + Cursor.lockState = CursorLockMode.Locked; + Invoke("CalibrationPointerPosition", 0.2f); + } + + /// + /// 校准指针位置 + /// + public void CalibrationPointerPosition() + { + //Cursor.lockState = CursorLockMode.None; + // 获取鼠标的窗口坐标 + Vector2 winPos = Input.mousePosition; + Vector2 center = new Vector2(Screen.width / 2, Screen.height / 2); + + //winPos = winPos - (winPos - center) * 2; + + //Debug.Log("窗口位置" + winPos + " " + center); + // 获取指针的屏幕坐标 + GuiMouse.POINT screenPos = GuiMouse.GetMousePos(); + //Debug.Log("屏幕位置" + screenPos); + //然后经过一系列的计算 嘿嘿 + offect = new Vector2(winPos.x - screenPos.X, winPos.y - screenPos.Y); + //Debug.Log("校准指针偏移" + offect); + Invoke("Xxxx", 0.2f); + } + void Xxxx() + { + Cursor.lockState = CursorLockMode.None; + } + public GuiMouse.POINT CalculationScreenPos(Vector2 winPos) + { + return new GuiMouse.POINT((int)(winPos.x - offect.x), (int)(Screen.height - winPos.y - offect.y)); + } + } +} \ No newline at end of file diff --git a/GuiHandle/Control.cs b/GuiHandle/Control.cs new file mode 100644 index 0000000..8f0759f --- /dev/null +++ b/GuiHandle/Control.cs @@ -0,0 +1,356 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace GuiHandle +{ + public class Control : MonoBehaviour + { + + //public bool btn_up;// 0 暂停(空格) + //public bool btn_down;// 1 关闭(esc) + //public bool btn_left;// 2 向前选择组件 + //public bool btn_right;// 3 向后选择组件 + + //public bool btn_l1;// 4 战斗后退大 + //public bool btn_r1;// 5 战斗前进大 + //public bool btn_l2;// 6 战斗后退小 + //public bool btn_r2;// 7 战斗前进小 + + //public bool btn_square;//□ 8 左键 + //public bool btn_circle;//○ 9 右键 + //public bool btn_triangle;//△ 10 上滚 + //public bool btn_x;//× 11 下滚 + /* + △ + □ ○ + × + */ + //public bool btn_pad;// 0 12 xx + //public bool btn_options;// 0 13 呼出/关闭mod管理器 + //public bool btn_share;// 0 14 xx + + + public static int last_boolvalue; + + public static Control instance; + public static float left_x; + public static float left_y; + public static float right_x; + public static float right_y; + public static int boolvalue; + public static byte num; + + public static ControlEnum controlEnum = ControlEnum.App; + + private void Awake() + { + instance = this; + } + + public void MyUpdate() + { + + Debug.Log(Control.controlEnum); + + + switch (controlEnum) + { + case ControlEnum.App: + left_x = ModReceivePage.left_x; + left_y = ModReceivePage.left_y; + right_x = ModReceivePage.right_x; + right_y = ModReceivePage.right_y; + boolvalue = ModReceivePage.boolvalue; + break; + default: + if (!Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.D)) + { + left_x = Input.GetAxis("Horizontal"); + } + if (!Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.X)) + { + left_y = Input.GetAxis("Vertical"); + } + + boolvalue = 0; + if (!Input.GetKey(KeyCode.Space))// 暂停 △ 0 + { + if (Input.GetAxis("Jump") > 0) + { + // 暂停 + Debug.Log("暂停" + (1 << 0)); + boolvalue |= 1 << 0; + } + } + if (!Input.GetMouseButton(0))// 左键 □ 8 + { + if (Input.GetAxis("Fire1") > 0) + { + // 左键 + Debug.Log("左键" + (1 << 8)); + boolvalue |= 1 << 8; + } + } + if (!Input.GetMouseButton(1))// 关闭 × 1 + { + if (Input.GetAxis("Fire2") > 0) + { + // 关闭 + Debug.Log("关闭" + (1 << 1)); + boolvalue |= 1 << 1; + } + } + if (!Input.GetMouseButton(2))// 选择UI ○ 3 + { + if (Input.GetAxis("Fire3") > 0) + { + // 选择 + Debug.Log("选择" + (1 << 3)); + boolvalue |= 1 << 3; + } + } + if (boolvalue > 0) + Debug.Log(last_boolvalue + " == " + boolvalue); + + + + //left_x = ModReceivePage.left_x; + //left_y = ModReceivePage.left_y; + //right_x = ModReceivePage.right_x; + //right_y = ModReceivePage.right_y; + //boolvalue = ModReceivePage.boolvalue; + + + break; + } + } + + public void MyLateUpdate() + { + switch (controlEnum) + { + case ControlEnum.App: + last_boolvalue = ModReceivePage.boolvalue; + break; + default: + last_boolvalue = boolvalue; + + + //left_x = ModReceivePage.left_x; + //left_y = ModReceivePage.left_y; + //right_x = ModReceivePage.right_x; + //right_y = ModReceivePage.right_y; + //boolvalue = ModReceivePage.boolvalue; + + + break; + } + } + + + /// + /// 是否触发选择控件 + /// + /// + public bool IsJudgment() + { + int keyA = 1 << ControlKey.SelectBack; + int keyB = 1 << ControlKey.SelectForward; + //Debug.Log(last_boolvalue + " " + boolvalue + " " + keyA + " " + keyB + " " + ((last_boolvalue & keyA) != keyA && (boolvalue & keyA) == keyA)); + //if (((last_boolvalue & keyA) != keyA && (boolvalue & keyA) == keyA) || ((last_boolvalue & keyB) != keyB && (boolvalue & keyB) == keyB)) + // Debug.Log("触发选择"); + return ((last_boolvalue & keyA) != keyA && (boolvalue & keyA) == keyA) || ((last_boolvalue & keyB) != keyB && (boolvalue & keyB) == keyB); + } + /// + /// 是否触发选择上一个控件 + /// + /// + public bool IsLast() + { + int keyA = 1 << ControlKey.SelectBack; + return (last_boolvalue & keyA) != keyA && (boolvalue & keyA) == 2; + } + /// + /// 是否触发鼠标左右滑动 + /// + /// + public float IsHorizontal() + { + return left_x; + } + /// + /// 是否触发鼠标上下滑动 + /// + /// + public float IsVertical() + { + return left_y; + } + /// + /// 是否触发鼠标左键按下 + /// + /// + public bool IsMouseLeftDoun() + { + int key = 1 << ControlKey.MouseLeft; + //Debug.Log("左键按下" + ((last_boolvalue & key) != key && (boolvalue & key) == key)); + //if ((last_boolvalue & key) != key && (boolvalue & key) == key) + // Debug.Log("触发鼠标左键按下"); + return (last_boolvalue & key) != key && (boolvalue & key) == key; + } + /// + /// 是否触发鼠标左键弹起 + /// + /// + public bool IsMouseLeftUp() + { + int key = 1 << ControlKey.MouseLeft; + return (last_boolvalue & key) == key && (boolvalue & key) != key; + } + /// + /// 是否触发鼠标右键按下 + /// + /// + public bool IsMouseRightDoun() + { + int key = 1 << ControlKey.MouseRight; + return (last_boolvalue & key) != key && (boolvalue & key) == key; + } + /// + /// 是否触发鼠标右键弹起 + /// + /// + public bool IsMouseRightUp() + { + int key = 1 << ControlKey.MouseRight; + return (last_boolvalue & key) == key && (boolvalue & key) != key; + } + /// + /// 是否触发点击esc + /// + /// + public bool IsClickEsc() + { + int key = 1 << ControlKey.Esc; + return (last_boolvalue & key) != key && (boolvalue & key) == key; + } + /// + /// 是否触发点击空格 + /// + /// + public bool IsClickSpace() + { + int key = 1 << ControlKey.Space; + return (last_boolvalue & key) != key && (boolvalue & key) == key; + } + /// + /// 是否触发战斗大步前进 + /// + /// + public bool IsForwardBig() + { + int key = 1 << ControlKey.BattleForwardBig; + return (last_boolvalue & key) != key && (boolvalue & key) == key; + } + /// + /// 是否触发战斗大步后退 + /// + /// + public bool IsBackBig() + { + int key = 1 << ControlKey.BattleBackBig; + return (last_boolvalue & key) != key && (boolvalue & key) == key; + } + /// + /// 是否触发战斗小步前进 + /// + /// + public bool IsForwardSmall() + { + int key = 1 << ControlKey.BattleForwardSmall; + return (last_boolvalue & key) != key && (boolvalue & key) == key; + } + /// + /// 是否触发战斗小步后退 + /// + /// + public bool IsBackSmall() + { + int key = 1 << ControlKey.BattleBackSmall; + return (last_boolvalue & key) != key && (boolvalue & key) == key; + } + /// + /// 是否触发了滚轮滑动 + /// + /// + public float IsScroll() + { + int keyA = 1 << ControlKey.MouseScrollUp; + int keyB = 1 << ControlKey.MouseScrollDown; + if ((boolvalue & keyA) == keyA && (boolvalue & keyB) == keyB) + { + return ((boolvalue & keyA) == keyA ? 0.5f : 0) + ((last_boolvalue & keyA) == keyA ? 0.5f : 0) + ((boolvalue & keyB) == keyB ? -0.5f : 0) + ((last_boolvalue & keyB) == keyB ? -0.5f : 0); + } + return 0; + } + + } + + public enum ControlEnum + { + App = 0, + CommonHand = 1, + } + + public static class ControlKey + { + public static int Space = 0; + public static int Esc = 1; + public static int SelectBack = 2; + public static int SelectForward = 3; + + public static int BattleBackBig = 4; + public static int BattleForwardBig = 5; + public static int BattleBackSmall = 6; + public static int BattleForwardSmall = 7; + + public static int MouseLeft = 8; + public static int MouseRight = 9; + public static int MouseScrollUp = 10; + public static int MouseScrollDown = 11; + + public static int xx1 = 12; + public static int SetMod = 13; + public static int xx3 = 14; + + + + + + + + + + + + //public static int Space { get; set; } + //public static int Esc { get; set; } + //public static int SelectBack { get; set; } + //public static int SelectForward { get; set; } + + //public static int BattleBackBig { get; set; } + //public static int BattleForwardBig { get; set; } + //public static int BattleBackSmall { get; set; } + //public static int BattleForwardSmall { get; set; } + + //public static int MouseLeft { get; set; } + //public static int MouseRight { get; set; } + //public static int MouseScrollUp { get; set; } + //public static int MouseScrollDown { get; set; } + + //public static int xx1 { get; set; } + //public static int SetMod { get; set; } + //public static int xx3 { get; set; } + } +} \ No newline at end of file diff --git a/GuiHandle/GuiHand.cs b/GuiHandle/GuiHand.cs new file mode 100644 index 0000000..2711b61 --- /dev/null +++ b/GuiHandle/GuiHand.cs @@ -0,0 +1,211 @@ +using System; +using System.Runtime.InteropServices; +using UnityEngine; +using UnityEngine.EventSystems; +using UnityEngine.UI; + +namespace GuiHandle +{ + public class GuiHand : MonoBehaviour + { + public Transform image; + public Camera uiCamera; + private EventSystem eventSystem; + Selectable select = null; + bool getCom = false; + Button btn = null; + CalculationScreenPosition calculationScreenPosition; + ModPublicizeIp modUDPPublicizeIp; + private void Awake() + { + calculationScreenPosition = gameObject.AddComponent(); + modUDPPublicizeIp = new ModPublicizeIp(); + modUDPPublicizeIp.Start(); + } + void Start() + { + this.eventSystem = EventSystem.current; + } + + /// + /// 触发鼠标点击 + /// + void MouseClick() + { + if (Control.instance.IsMouseLeftDoun()) + { + GuiMouse.MouseLeftDown(); + } + if (Control.instance.IsMouseLeftUp()) + { + GuiMouse.MouseLeftUp(); + } + } + + /// + /// 选择按钮 + /// + void SelectBtn() + { + if (Control.instance.IsJudgment()) + { + //Debug.Log("触发了选择"); + Selectable next = null; + Selectable current = null; + + // 找出我们是否有一个有效的当前选择的游戏对象 + if (eventSystem.currentSelectedGameObject != null) + { + // Unity似乎没有“取消选择”一个不活动的对象 + if (eventSystem.currentSelectedGameObject.activeInHierarchy) + { + current = eventSystem.currentSelectedGameObject.GetComponent(); + } + } + if (current != null) + { + // 当SHIFT与标签一起被按住时,向后移动而不是向前移动 + if (Control.instance.IsLast()) + { + //Debug.Log("触发了向前选择"); + next = current.FindSelectableOnLeft(); + if (next == null) + { + next = current.FindSelectableOnUp(); + } + } + else + { + //Debug.Log("触发了向后选择"); + next = current.FindSelectableOnRight(); + if (next == null) + { + next = current.FindSelectableOnDown(); + if (next == null) + { + current = eventSystem.firstSelectedGameObject.GetComponent(); + next = current; + } + } + } + } + else + { + // 如果没有当前选择的游戏对象,选择第一个 + if (Selectable.allSelectables.Count > 0) + { + next = Selectable.allSelectables[0]; + getCom = false; + } + } + + if (next != null) + { + next.Select(); + select = next; + image.SetParent(next.transform, false); + + + + Vector2 winPos = uiCamera.WorldToScreenPoint(image.transform.position); + var screenPos = calculationScreenPosition.CalculationScreenPos(winPos); + GuiMouse.SetMousePos(screenPos); + } + } + } + + /// + /// 指针移动 + /// + void MouseMove() + { + float h = Control.instance.IsHorizontal(); + float v = Control.instance.IsVertical(); + if (v != 0 || h != 0) + { + GuiMouse.POINT pt = GuiMouse.GetMousePos(); + pt.X += (int)(h * 10); + pt.Y -= (int)(v * 10); + GuiMouse.SetMousePos(pt); + } + } + + /// + /// 指针滑动 + /// + void MouseScroll() + { + float value = Control.instance.IsScroll(); + if (value != 0) + { + value = value * 100; + GuiMouse.MouseScroll((int)value); + } + } + + void KeyboardClick() + { + if (Control.instance.IsClickEsc()) + GuiKeyboard.KeyboardClick(27); + + if (Control.instance.IsClickSpace()) + GuiKeyboard.KeyboardClick(32); + + if (Control.instance.IsForwardBig()) + GuiKeyboard.KeyboardClick(101); + + if (Control.instance.IsBackBig()) + GuiKeyboard.KeyboardClick(113); + + if (Control.instance.IsForwardSmall()) + GuiKeyboard.KeyboardClick(100); + + if (Control.instance.IsBackSmall()) + GuiKeyboard.KeyboardClick(97); + } + + void Update() + { + ModUDP.instance.MyUpdate(); + Control.instance.MyUpdate(); + + SelectBtn(); + MouseMove(); + MouseClick(); + MouseScroll(); + KeyboardClick(); + + //if (Input.anyKeyDown) + //{ + + // Debug.Log(Event.current.keyCode); + // //Event e = Event.current; + // //if (e.isKey) + // //{ + // // KeyCode currentKey = e.keyCode; + // // int i = (int)currentKey; + // // Debug.LogWarning("Current Key is : " + currentKey.ToString() + " " + i); + // //} + //} + + Control.instance.MyLateUpdate(); + } + + //private void OnGUI() + //{ + // if (Input.anyKeyDown) + // { + + // Debug.LogWarning(Event.current.keyCode); + // //Event e = Event.current; + // //if (e.isKey) + // //{ + // // KeyCode currentKey = e.keyCode; + // // int i = (int)currentKey; + // // Debug.LogWarning("Current Key is : " + currentKey.ToString() + " " + i); + // //} + // } + //} + } + +} \ No newline at end of file diff --git a/GuiHandle/GuiHandle.cs b/GuiHandle/GuiHandle.cs new file mode 100644 index 0000000..e90a04d --- /dev/null +++ b/GuiHandle/GuiHandle.cs @@ -0,0 +1,81 @@ +using Harmony12; +using System; +using System.Collections.Generic; +using System.Reflection; +using UnityEngine; +using UnityEngine.UI; +using UnityModManagerNet; +using System.Text.RegularExpressions; +using System.Linq; +using System.Reflection.Emit; +using System.Text; + +namespace GuiHandle +{ + public class Settings : UnityModManager.ModSettings + { + public override void Save(UnityModManager.ModEntry modEntry) + { + UnityModManager.ModSettings.Save(this, modEntry); + } + + } + public static class Main + { + public static bool enabled; + public static Settings settings; + public static UnityModManager.ModEntry.ModLogger Logger; + + + public static bool Load(UnityModManager.ModEntry modEntry) + { + #region 基础设置 + settings = Settings.Load(modEntry); + Logger = modEntry.Logger; + modEntry.OnToggle = OnToggle; + modEntry.OnGUI = OnGUI; + modEntry.OnSaveGUI = OnSaveGUI; + + HarmonyInstance harmony = HarmonyInstance.Create(modEntry.Info.Id); + harmony.PatchAll(Assembly.GetExecutingAssembly()); + #endregion + + return true; + } + + static string title = "鬼之手 1.0.0"; + public static bool OnToggle(UnityModManager.ModEntry modEntry, bool value) + { + enabled = value; + return true; + } + static void OnSaveGUI(UnityModManager.ModEntry modEntry) + { + settings.Save(modEntry); + } + + static bool isCreate = false; + static void OnGUI(UnityModManager.ModEntry modEntry) + { + GUILayout.Label(title, GUILayout.Width(300)); + + if (!isCreate) + { + isCreate = true; + + + var obj = new GameObject(); + obj.name = "GuiHandle"; + UnityEngine.Object.DontDestroyOnLoad(obj); + obj.AddComponent(); + obj.AddComponent(); + obj.AddComponent(); + obj.AddComponent(); + obj.AddComponent(); + + Logger.Log(obj.ToString()); + } + } + + } +} \ No newline at end of file diff --git a/GuiHandle/GuiMouse.cs b/GuiHandle/GuiMouse.cs new file mode 100644 index 0000000..2c5d816 --- /dev/null +++ b/GuiHandle/GuiMouse.cs @@ -0,0 +1,104 @@ + +using System; +using System.Runtime.InteropServices; + +namespace GuiHandle +{ + public static class GuiMouse + { + #region 指针移动 + [StructLayout(LayoutKind.Sequential)] + public struct POINT + { + public int X; + public int Y; + + public POINT(int x, int y) + { + this.X = x; + this.Y = y; + } + + public override string ToString() + { + return ("X:" + X + ", Y:" + Y); + } + } + + [DllImport("user32.dll", CharSet = CharSet.Auto)] + static extern bool GetCursorPos(out POINT pt); + + + + [DllImport("user32.dll")] //引入dll + static extern int SetCursorPos(int x, int y); + + public static POINT GetMousePos() + { + POINT pt; + GetCursorPos(out pt); + return pt; + } + + public static void SetMousePos(POINT pt) + { + SetCursorPos(pt.X, pt.Y); + } + #endregion + [DllImport("user32.dll")] + static extern void mouse_event(MouseEventFlag flags, int dx, int dy, int buttons, UIntPtr extraInfo); + + static bool hasMouseDown = false; + [Flags] + enum MouseEventFlag : uint + { + Move = 0x0001, + LeftDown = 0x0002, + LeftUp = 0x0004, + RightDown = 0x0008, + RightUp = 0x0010, + MiddleDown = 0x0020, + MiddleUp = 0x0040, + XDown = 0x0080, + XUp = 0x0100, + Wheel = 0x0800, + VirtualDesk = 0x4000, + Absolute = 0x8000 + } + + public static void MouseLeftDown() + { + mouse_event(MouseEventFlag.LeftDown, 0, 0, 0, UIntPtr.Zero); + } + + public static void MouseLeftUp() + { + mouse_event(MouseEventFlag.LeftUp, 0, 0, 0, UIntPtr.Zero); + } + + /// + /// + /// + /// 负数是下滑,正数是上滑 一般-100 +100 + /// + public static void MouseScroll(int value) + { + mouse_event(MouseEventFlag.Wheel, 0, 0, value, UIntPtr.Zero); + } + } + + public static class GuiKeyboard + { + [DllImport("user32.dll", EntryPoint = "keybd_event")] + static extern void Keybd_event( + int bvk,//虚拟键值 ESC键对应的是27 + int bScan,//0 + int dwFlags,//0为按下,1按住,2释放 + int dwExtraInfo//0 + ); + public static void KeyboardClick(int key) + { + Keybd_event(key, 0, 0, 0); + } + } +} \ No newline at end of file diff --git a/GuiHandle/Info.json b/GuiHandle/Info.json new file mode 100644 index 0000000..e048f42 --- /dev/null +++ b/GuiHandle/Info.json @@ -0,0 +1,7 @@ +{ + "Id": "GuiHandle", + "DisplayName": "鬼之手", + "Version": "1.0.0", + "AssemblyName": "GuiHandle.dll", + "EntryMethod": "GuiHandle.Main.Load" +} \ No newline at end of file diff --git a/GuiHandle/ModUDP.cs b/GuiHandle/ModUDP.cs new file mode 100644 index 0000000..eb8a771 --- /dev/null +++ b/GuiHandle/ModUDP.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading; +using UnityEngine; + +namespace GuiHandle +{ + public class ModUDP : MonoBehaviour + { + public static ModUDP instance; + public static List sockets = new List(); + private void Awake() + { + instance = this; + } + + public static string message; + private void Start() + { + Thread thread = new Thread(StartUDP); + thread.Start(); + } + + private void StartUDP() + { + ModReceivePage modReceivePage = new ModReceivePage(); + modReceivePage.OnServerInitialized(); + } + + public void MyUpdate() + { + Main.Logger.Log(message); + } + + private void OnDestroy() + { + foreach (var item in sockets) + { + item.Close(); + } + } + } + + + + + // 接收操作数据 + public class ModReceivePage + { + public static ModReceivePage instance; + + public static float left_x; + public static float left_y; + public static float right_x; + public static float right_y; + public static short boolvalue; + public static byte num; + + public ModReceivePage() + { + if (instance != null) + { + return; + } + instance = this; + } + + public void OnServerInitialized() + { + Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + ModUDP.sockets.Add(sock); + IPEndPoint iep = new IPEndPoint(IPAddress.Any, 9158); + sock.Bind(iep); + while (true) + { + EndPoint ep = (EndPoint)iep; + byte[] data = new byte[11]; + int recv = sock.ReceiveFrom(data, ref ep); + + int idx = 0; + byte num = data[idx++]; + if ((num < 75 && ModReceivePage.num > 150) || ModReceivePage.num < num) + { + ModReceivePage.num = num; + short leftx = BitConverter.ToInt16(data, 1); + short lefty = BitConverter.ToInt16(data, 3); + short rightx = BitConverter.ToInt16(data, 5); + short righty = BitConverter.ToInt16(data, 7); + boolvalue = BitConverter.ToInt16(data, 9); + left_x = (float)leftx / 10000; + left_y = (float)lefty / 10000; + right_x = (float)rightx / 10000; + right_y = (float)righty / 10000; + + + ModUDP.message = data[0] + "\t" + data[1] + "\t" + data[2] + "\t" + data[3] + "\t" + data[4] + "\t" + data[5] + "\t" + data[6] + "\t" + data[7] + "\t" + data[8] + "\t" + data[9] + "\t" + data[10]; + } + Thread.Sleep(0); + } + } + } + + + + + + + // 广播IP地址 + public class ModPublicizeIp + { + private Socket sock; + private IPEndPoint iep1; + private byte[] data; + public void Start() + { + sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + ModUDP.sockets.Add(sock); + //255.255.255.255 + iep1 = new IPEndPoint(IPAddress.Broadcast, 9159); + string hostname = Dns.GetHostName(); + data = Encoding.ASCII.GetBytes(hostname); + sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); + Thread t = new Thread(BroadcastMessage); + t.Start(); + } + private void BroadcastMessage() + { + while (true) + { + sock.SendTo(data, iep1); + Thread.Sleep(2000); + } + } + + public void Close() + { + sock.Close(); + } + } +} \ No newline at end of file diff --git a/GuiHandle/Readme.md b/GuiHandle/Readme.md new file mode 100644 index 0000000..fb87059 --- /dev/null +++ b/GuiHandle/Readme.md @@ -0,0 +1,4 @@ +鬼之手 + +1.0.0 +ps4手柄可以控制游戏 \ No newline at end of file diff --git a/GuiHandle/Test.cs b/GuiHandle/Test.cs new file mode 100644 index 0000000..361dd31 --- /dev/null +++ b/GuiHandle/Test.cs @@ -0,0 +1,89 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace GuiHandle +{ + public class Test : MonoBehaviour + { + public void Start() + { + int i = 0; + foreach (Transform item in transform) + { + Button btn = item.GetComponent