From b9d8b32f32ca844aecf0846ab04ba61e7c70cb6f Mon Sep 17 00:00:00 2001 From: Strackeror Date: Thu, 28 Jul 2022 11:02:49 +0200 Subject: [PATCH 01/39] Convenient Spiribirds, Typescript version --- .../ConvenientSpiribird.ts | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 mod/ConvenientSpiribirds/ConvenientSpiribird.ts diff --git a/mod/ConvenientSpiribirds/ConvenientSpiribird.ts b/mod/ConvenientSpiribirds/ConvenientSpiribird.ts new file mode 100644 index 0000000..445ffea --- /dev/null +++ b/mod/ConvenientSpiribirds/ConvenientSpiribird.ts @@ -0,0 +1,51 @@ +import LvBuffCageId = snow.data.ContentsIdSystem.LvBuffCageId.T; + +type Test = System.Array.Generic.T + + +let SPIRIBIRD_MULTIPLIER = 2 + +let player = sdk.get_managed_singleton("snow.player.PlayerManager") +if (!player) { + let modded_ids: LvBuffCageId[] = [] + sdk.hook( + sdk.find_type_definition("snow.data.EquipmentInventoryData").get_method("getLvBuffCageData"), + undefined, + (retval) => { + let t = sdk.to_managed_object(retval) + let param = sdk.to_managed_object(retval).downCastAsNormal()._Param + if (modded_ids.includes(param._Id)) { + return retval + } + modded_ids.push(param._Id) + let arr = param._StatusBuffAddValue; + for (let i = 0; i < arr.get_Length(); ++i) { + log.info(`${param._Id}[${i}]=${arr.get_Item(i)}`) + arr[i] = arr[i] * SPIRIBIRD_MULTIPLIER; + } + + return retval + } + ) +} + +let next_stamina_max = 0.0 +let next_player: snow.player.PlayerQuestBase.T; +let f = sdk.hook( + sdk + .find_type_definition("snow.player.PlayerQuestBase") + .get_method("calcLvBuffStamina"), + ([_1, self, cnt]) => { + let player = sdk.to_managed_object(self); + let count = sdk.to_int64(cnt); + + next_stamina_max = count * 30; + next_player = player; + }, + + () => { + next_player.calcStaminaMax(next_stamina_max, false); + } +); + +export {}; \ No newline at end of file From 3fcc4f523d21c0d07e663199b8c99b95dada0527 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Thu, 28 Jul 2022 11:02:49 +0200 Subject: [PATCH 02/39] Remove mod.ts --- mod/mod.ts | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 mod/mod.ts diff --git a/mod/mod.ts b/mod/mod.ts deleted file mode 100644 index 2353429..0000000 --- a/mod/mod.ts +++ /dev/null @@ -1,9 +0,0 @@ -import {snow} from "../IL2CPP/il2cpp" - -sdk.hook( - snow.player.PlayerWeaponCtrl.M.start, - ([_, self]) => { - let obj = sdk.to_managed_object(self) - obj._bodyConstScale = 1.0 - } -) From 2bf21a396fdaa68670e30c2ce3df62cb5f31fc55 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Thu, 28 Jul 2022 11:02:49 +0200 Subject: [PATCH 03/39] Add investigations, update convenient spiribirds, mono-repo style --- IL2CPP/type-filters.json | 10 +- .../ConvenientSpiribird.ts | 15 +- mod/ConvenientSpiribirds/tsconfig.json | 31 ++++ mod/Investigations/Investigation.ts | 22 +++ mod/Investigations/QuestGenerator.ts | 162 ++++++++++++++++++ mod/Investigations/Utilities.ts | 16 ++ mod/Investigations/tsconfig.json | 31 ++++ tsconfig.json | 16 -- 8 files changed, 273 insertions(+), 30 deletions(-) create mode 100644 mod/ConvenientSpiribirds/tsconfig.json create mode 100644 mod/Investigations/Investigation.ts create mode 100644 mod/Investigations/QuestGenerator.ts create mode 100644 mod/Investigations/Utilities.ts create mode 100644 mod/Investigations/tsconfig.json delete mode 100644 tsconfig.json diff --git a/IL2CPP/type-filters.json b/IL2CPP/type-filters.json index 0237818..f1bd882 100644 --- a/IL2CPP/type-filters.json +++ b/IL2CPP/type-filters.json @@ -1,7 +1,7 @@ [ - "snow.data", - "snow.player", - "snow.quest", - "snow.QuestManager", - "snow.SnowSingleton" + "^snow.data", + "^snow.player.[!f]", + "^snow.quest", + "^snow.QuestManager", + "^snow.SnowSingleton" ] \ No newline at end of file diff --git a/mod/ConvenientSpiribirds/ConvenientSpiribird.ts b/mod/ConvenientSpiribirds/ConvenientSpiribird.ts index 445ffea..6265f46 100644 --- a/mod/ConvenientSpiribirds/ConvenientSpiribird.ts +++ b/mod/ConvenientSpiribirds/ConvenientSpiribird.ts @@ -1,6 +1,5 @@ -import LvBuffCageId = snow.data.ContentsIdSystem.LvBuffCageId.T; - -type Test = System.Array.Generic.T +import {snow} from "ConvenientSpiribirds/IL2CPP/il2cpp" +import LvBuffCageId = snow.data.ContentsIdSystem.LvBuffCageId; let SPIRIBIRD_MULTIPLIER = 2 @@ -12,7 +11,6 @@ if (!player) { sdk.find_type_definition("snow.data.EquipmentInventoryData").get_method("getLvBuffCageData"), undefined, (retval) => { - let t = sdk.to_managed_object(retval) let param = sdk.to_managed_object(retval).downCastAsNormal()._Param if (modded_ids.includes(param._Id)) { return retval @@ -30,11 +28,9 @@ if (!player) { } let next_stamina_max = 0.0 -let next_player: snow.player.PlayerQuestBase.T; -let f = sdk.hook( - sdk - .find_type_definition("snow.player.PlayerQuestBase") - .get_method("calcLvBuffStamina"), +let next_player: snow.player.PlayerQuestBase; +sdk.hook( + snow.player.PlayerQuestBase.M.calcLvBuffStamina, ([_1, self, cnt]) => { let player = sdk.to_managed_object(self); let count = sdk.to_int64(cnt); @@ -44,6 +40,7 @@ let f = sdk.hook( }, () => { + log.info(`calc buff stamina override ${next_stamina_max}`) next_player.calcStaminaMax(next_stamina_max, false); } ); diff --git a/mod/ConvenientSpiribirds/tsconfig.json b/mod/ConvenientSpiribirds/tsconfig.json new file mode 100644 index 0000000..0608fa3 --- /dev/null +++ b/mod/ConvenientSpiribirds/tsconfig.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://raw.githubusercontent.com/TypeScriptToLua/TypeScriptToLua/master/tsconfig-schema.json", + "compilerOptions": { + "lib": [ + "ESNext" + ], + "types": [ + "lua-types/5.4" + ], + "incremental": true, + "outDir": "./dist/ConvenientSpiribirds", + "baseUrl": ".", + "paths": { + "ConvenientSpiribirds/IL2CPP/*": [ + "../../IL2CPP/*" + ], + "ConvenientSpiribirds/*": [ + "./*" + ] + } + }, + "tstl": { + "luaLibImport": "inline", + "luaTarget": "5.3", + "measurePerformance": true, + }, + "include": [ + "./*", + "../../IL2CPP/*" + ] +} \ No newline at end of file diff --git a/mod/Investigations/Investigation.ts b/mod/Investigations/Investigation.ts new file mode 100644 index 0000000..e4b5ed3 --- /dev/null +++ b/mod/Investigations/Investigation.ts @@ -0,0 +1,22 @@ + +sdk.hook( + sdk.find_type_definition("snow.QuestManager").get_method("questEnemyDie"), + ([_, self, mon]) => { + let quest_mgr = sdk.to_managed_object(self) + + if (quest_mgr.getQuestRank_Lv() != 3) { + return + } + quest_mgr._QuestDataDictionary + let monster = sdk.to_managed_object(mon) + let monster_id = monster.get_EnemyType() + } +) + +sdk.find_type_definition("snow.QuestManager").get_method("questActivate") + +declare namespace A { + let b: number + function a(): number +} + diff --git a/mod/Investigations/QuestGenerator.ts b/mod/Investigations/QuestGenerator.ts new file mode 100644 index 0000000..fc98ca8 --- /dev/null +++ b/mod/Investigations/QuestGenerator.ts @@ -0,0 +1,162 @@ +import { create_array } from "./Utilities"; + +let QuestData = sdk.find_type_definition("snow.quest.QuestData"); +let NormalQuestData = sdk.find_type_definition( + "snow.quest.NormalQuestData.Param" +); +let EnemyQuestData = sdk.find_type_definition( + "snow.quest.NormalQuestDataForEnemy.Param" +); + +function create_base_quest_data() { + let normal_quest_data = NormalQuestData.create_instance(true); + { + normal_quest_data._DbgName = "InvestigationName"; + normal_quest_data._DbgClient = "InvestigationClient"; + normal_quest_data._DbgContent = "InvestigationContent"; + + normal_quest_data._QuestNo = 942001; + normal_quest_data._QuestType = 0; + normal_quest_data._QuestLv = 5; + normal_quest_data._EnemyLv = 3; + normal_quest_data._MapNo = 1; + normal_quest_data._BaseTime = 11; + normal_quest_data._TimeVariation = 3; + normal_quest_data._TimeLimit = 50; + normal_quest_data._QuestLife = 3; // carts + + normal_quest_data._OrderType = create_array( + "snow.quest.QuestOrderType", + [0x10, 0] + ); // Starting conditions + normal_quest_data._TargetType = create_array( + "snow.quest.QuestTargetType", + [0, 0] + ); // Objectives + normal_quest_data._TgtEmType = create_array( + "snow.enemy.EnemyDef.EmTypes", + [0, 0] + ); + normal_quest_data._TgtItemId = create_array( + "snow.data.ContentsIdSystem.ItemId", + [0x4000000, 0x4000000] + ); + normal_quest_data._TgtNum = create_array("System.UInt32", [0, 0]); + + normal_quest_data._BossEmType = create_array( + "snow.enemy.EnemyDef.EmTypes", + [0, 0, 0, 0, 0, 0, 0] + ); + normal_quest_data._BossSetCondition = create_array( + "snow.QuestManager.BossSetCondition", + [0, 0, 0, 0, 0, 0, 0] + ); + normal_quest_data._BossSetParam = create_array( + "System.UInt32", + [0, 0, 0, 0, 0, 0, 0] + ); + + normal_quest_data._InitExtraEmNum = 0; + + normal_quest_data._SwapEmRate = create_array("System.Byte", [0, 0]); + normal_quest_data._SwapSetCondition = create_array( + "snow.QuestManager.SwapSetCondition", + [0, 0] + ); + normal_quest_data._SwapSetParam = create_array("System.Byte", [0, 0]); + normal_quest_data._SwapExitTime = create_array("System.Byte", [0, 0]); + normal_quest_data._SwapStopType = 0; + normal_quest_data._SwapStopParam = 0; + normal_quest_data._SwapExecType = 0; + + normal_quest_data._RemMoney = 0; + normal_quest_data._RemVillagePoint = 0; + normal_quest_data._RemRankPoint = 0; + + normal_quest_data._SupplyTbl = 310001; + normal_quest_data._Icon = create_array( + "snow.gui.SnowGuiCommonUtility.Icon.EnemyIconFrameForQuestOrder", + [999, 999, 999, 999, 999] + ); + normal_quest_data._IsTutorial = false; + normal_quest_data._IsFromNpc = false; + normal_quest_data._AutoMatchHR = 20011; + normal_quest_data._BattleBGMType = 0; + normal_quest_data._ClearBGMType = 0; + } + + let enemy_quest_data = EnemyQuestData.create_instance(true); + { + enemy_quest_data._EmsSetNo = 34; + enemy_quest_data._ZakoVital = 130; + enemy_quest_data._ZakoAttack = 123; + enemy_quest_data._ZakoParts = 149; + enemy_quest_data._ZakoOther = 137; + enemy_quest_data._ZakoMulti = 0; + + enemy_quest_data._RouteNo = create_array( + "System.Byte", + [0, 0, 0, 0, 0, 0, 0] + ); + enemy_quest_data._PartsTbl = create_array( + "System.UInt16", + [0, 0, 0, 0, 0, 0, 0] + ); + enemy_quest_data._InitSetName = create_array("System.String", [ + "", + "", + "", + "", + "", + "", + "", + ]); + enemy_quest_data._SubType = create_array( + "System.Byte", + [0, 0, 0, 0, 0, 0, 0] + ); + enemy_quest_data._VitalTbl = create_array( + "System.UInt16", + [0, 0, 0, 0, 0, 0, 0] + ); + enemy_quest_data._AttackTbl = create_array( + "System.UInt16", + [0, 0, 0, 0, 0, 0, 0] + ); + enemy_quest_data._OtherTbl = create_array( + "System.UInt16", + [0, 0, 0, 0, 0, 0, 0] + ); + enemy_quest_data._StaminaTbl = create_array( + "System.Byte", + [0, 0, 0, 0, 0, 0, 0] + ); + enemy_quest_data._Scale = create_array( + "System.Byte", + [0, 0, 0, 0, 0, 0, 0] + ); + enemy_quest_data._ScaleTbl = create_array( + "snow.enemy.EnemyDef.BossScaleTblType", + [0, 0, 0, 0, 0, 0, 0] + ); + enemy_quest_data._Difficulty = create_array( + "snow.enemy.EnemyDef.NandoYuragi", + [0, 0, 0, 0, 0, 0, 0] + ); + enemy_quest_data._BossMulti = create_array( + "System.Byte", + [0, 0, 0, 0, 0, 0, 0] + ); + enemy_quest_data._IndividualType = create_array( + "snow.enemy.EnemyDef.EnemyIndividualType", + [0, 0, 0, 0, 0, 0, 0] + ); + } + + let quest_data = QuestData.create_instance(true); + quest_data.set_RawNormal(normal_quest_data); + quest_data.set_RawEnemy(enemy_quest_data); +} + +export function create_investigation() { +} \ No newline at end of file diff --git a/mod/Investigations/Utilities.ts b/mod/Investigations/Utilities.ts new file mode 100644 index 0000000..c7d38e0 --- /dev/null +++ b/mod/Investigations/Utilities.ts @@ -0,0 +1,16 @@ +import { System } from "Investigations/IL2CPP/il2cpp"; + +export function create_array( + type: string, + table: any[] +): System.Array.Generic; +export function create_array( + type: T, + table: REType[] +): System.Array.Generic> { + let array = sdk.create_managed_array(type, table.length); + for (let i = 0; i < table.length; ++i) { + array[i] = table[i]; + } + return array; +} diff --git a/mod/Investigations/tsconfig.json b/mod/Investigations/tsconfig.json new file mode 100644 index 0000000..ff09a81 --- /dev/null +++ b/mod/Investigations/tsconfig.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://raw.githubusercontent.com/TypeScriptToLua/TypeScriptToLua/master/tsconfig-schema.json", + "compilerOptions": { + "lib": [ + "ESNext" + ], + "types": [ + "lua-types/5.4" + ], + "incremental": true, + "outDir": "./dist/Investigations", + "baseUrl": ".", + "paths": { + "Investigations/IL2CPP/*": [ + "../../IL2CPP/*" + ], + "Investigations/*": [ + "./*" + ] + } + }, + "tstl": { + "luaLibImport": "inline", + "luaTarget": "5.3", + "measurePerformance": true, + }, + "include": [ + "./**/*", + "../../IL2CPP/*" + ] +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index 96da353..0000000 --- a/tsconfig.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/TypeScriptToLua/TypeScriptToLua/master/tsconfig-schema.json", - "compilerOptions": { - "outDir": "dist", - "lib": ["ESNext"], - "types": [ - "lua-types/5.4" - ], - "incremental": true - }, - "tstl": { - "luaTarget": "5.3", - "luaLibImport": "inline", - "measurePerformance": true, - } -} From a8844d9864e08e5c223ea41e29a7099d0a3eaac8 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Thu, 28 Jul 2022 11:03:18 +0200 Subject: [PATCH 04/39] Reorganize mod projects, port full investigations --- .gitignore | 4 +- .vscode/settings.json | 3 +- .../ConvenientSpiribird.ts | 2 +- .../dist/ConvenientSpiribirds.lua | 1 + mod/ConvenientSpiribirds/tsconfig.json | 7 +- mod/Investigations/Investigation.ts | 152 +- mod/Investigations/InvestigationData.ts | 4627 +++++++++++++++++ mod/Investigations/QuestGenerator.ts | 151 +- mod/Investigations/Utilities.ts | 14 +- mod/Investigations/dist/Investigations.lua | 1 + mod/Investigations/tsconfig.json | 7 +- 11 files changed, 4927 insertions(+), 42 deletions(-) create mode 100644 mod/ConvenientSpiribirds/dist/ConvenientSpiribirds.lua create mode 100644 mod/Investigations/InvestigationData.ts create mode 100644 mod/Investigations/dist/Investigations.lua diff --git a/.gitignore b/.gitignore index 4472e53..9aaafa8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ il2cpp_dump.json il2cpp.d.ts typemap.d.ts -dist/ +**/dist/*/* node_modules/ -output/ \ No newline at end of file +output/ diff --git a/.vscode/settings.json b/.vscode/settings.json index a4c25ec..7bf4c24 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,6 @@ { "Lua.diagnostics.globals": [ "sdk" - ] + ], + "typescript.preferences.importModuleSpecifier": "non-relative" } \ No newline at end of file diff --git a/mod/ConvenientSpiribirds/ConvenientSpiribird.ts b/mod/ConvenientSpiribirds/ConvenientSpiribird.ts index 6265f46..16ebf44 100644 --- a/mod/ConvenientSpiribirds/ConvenientSpiribird.ts +++ b/mod/ConvenientSpiribirds/ConvenientSpiribird.ts @@ -1,4 +1,4 @@ -import {snow} from "ConvenientSpiribirds/IL2CPP/il2cpp" +import {snow} from "ConvenientSpiribirds/IL2CPP" import LvBuffCageId = snow.data.ContentsIdSystem.LvBuffCageId; diff --git a/mod/ConvenientSpiribirds/dist/ConvenientSpiribirds.lua b/mod/ConvenientSpiribirds/dist/ConvenientSpiribirds.lua new file mode 100644 index 0000000..3eed9ef --- /dev/null +++ b/mod/ConvenientSpiribirds/dist/ConvenientSpiribirds.lua @@ -0,0 +1 @@ +require("ConvenientSpiribirds.ConvenientSpiribird") diff --git a/mod/ConvenientSpiribirds/tsconfig.json b/mod/ConvenientSpiribirds/tsconfig.json index 0608fa3..ddeefd8 100644 --- a/mod/ConvenientSpiribirds/tsconfig.json +++ b/mod/ConvenientSpiribirds/tsconfig.json @@ -7,15 +7,12 @@ "types": [ "lua-types/5.4" ], - "incremental": true, "outDir": "./dist/ConvenientSpiribirds", "baseUrl": ".", "paths": { - "ConvenientSpiribirds/IL2CPP/*": [ - "../../IL2CPP/*" - ], "ConvenientSpiribirds/*": [ - "./*" + "./*", + "../../IL2CPP/*" ] } }, diff --git a/mod/Investigations/Investigation.ts b/mod/Investigations/Investigation.ts index e4b5ed3..59a78bf 100644 --- a/mod/Investigations/Investigation.ts +++ b/mod/Investigations/Investigation.ts @@ -1,22 +1,144 @@ +import { snow } from "Investigations/IL2CPP"; +import { + create_investigation, + generate_quest_data, + get_monster_name, + update_quest_no, +} from "Investigations/QuestGenerator"; +import QCF = snow.gui.fsm.questcounter.GuiQuestCounterFsmManager; +export interface Investigation { + map: number; + target_monster: number; + extra_monster: [number, number]; + pinned: boolean; + quest_data?: snow.quest.QuestData; +} + +let current_investigation_data: { + current_player: string; + investigations: Investigation[]; +} = { current_player: "", investigations: [] }; + +let investigation_id_map: { + [idx: number]: Investigation; +} = {}; + +function get_investigations(): Investigation[] { + const current_name = snow.SnowSaveService.M.Instance?.getCurrentHunterName(); + if (!current_name) { + return; + } + if (current_investigation_data.current_player == current_name) { + return current_investigation_data.investigations; + } + + current_investigation_data.investigations = json.load_file( + `Investigations/${current_name}.json` + ); + for (let i of current_investigation_data.investigations) { + i.quest_data = generate_quest_data(i); + } + return current_investigation_data.investigations; +} + +function save_investigations() { + const current_name = snow.SnowSaveService.M.Instance?.getCurrentHunterName(); + if (!current_name) { + return; + } + json.dump_file( + `Investigations/${current_name}.json`, + current_investigation_data + ); +} + +let next_returned_text: string = undefined sdk.hook( - sdk.find_type_definition("snow.QuestManager").get_method("questEnemyDie"), - ([_, self, mon]) => { - let quest_mgr = sdk.to_managed_object(self) - - if (quest_mgr.getQuestRank_Lv() != 3) { - return - } - quest_mgr._QuestDataDictionary - let monster = sdk.to_managed_object(mon) - let monster_id = monster.get_EnemyType() + snow.quest.QuestData.M.getQuestTextCore, + (args) => { + let self = sdk.to_managed_object(args[1]) + let quest_text: snow.quest.QuestText = sdk.to_int64(args[2]) + + next_returned_text = undefined + + let inv = investigation_id_map[self.getQuestNo()] + if (!inv) { + return + } + + switch (quest_text) { + case snow.quest.QuestText.TITLE: + next_returned_text = `Investigation: ${get_monster_name(inv.target_monster)}` + break; + case snow.quest.QuestText.CLIENT: + next_returned_text = "Investigator" + break; + case snow.quest.QuestText.TARGET: + next_returned_text = `Hunt a ${get_monster_name(inv.target_monster)}` + break; + } + + if (next_returned_text != undefined) { + return sdk.PreHookresult.SKIP_ORIGINAL } + }, + + (retval) => { + if (next_returned_text) { + return sdk.to_ptr(sdk.create_managed_string(next_returned_text)) + } + return retval + } ) -sdk.find_type_definition("snow.QuestManager").get_method("questActivate") +sdk.hook(snow.QuestManager.M.questEnemyDie, ([_, self, mon]) => { + let quest_mgr = sdk.to_managed_object(self); -declare namespace A { - let b: number - function a(): number -} + if (quest_mgr.getQuestRank_Lv() != snow.QuestManager.QuestRank.Master) { + return; + } + quest_mgr._QuestDataDictionary; + let monster = sdk.to_managed_object(mon); + let monster_id = monster.get_EnemyType(); + if (snow.QuestManager.M.Instance.getQuestRank_Lv() != snow.QuestManager.QuestRank.Master) { + return + } + + let inv = create_investigation(snow.SnowSaveService.M.Instance.getCurrentHunterName(), monster_id) + if (!inv) { + return + } + + inv.quest_data = generate_quest_data(inv) + get_investigations().push(inv) + save_investigations() +}); + +sdk.hook(snow.QuestManager.M.makeQuestNoList, undefined, (retval) => { + let questCounter = + snow.gui.fsm.questcounter.GuiQuestCounterFsmManager.M.Instance; + let questManager = snow.QuestManager.M.Instance; + + if ( + questCounter.getQuestCounterSelectedTopMenu() == + QCF.QuestCounterTopMenuType.Normal_Hall_Master && + questCounter.getQuestCounterSelectedRankMenu() == + QCF.QuestCounterRankMenuType.Master && + questCounter.getQuestCounterSelectedLevelMenu() == + QCF.QuestCounterLevelMenuType.Gathering + ) { + let list = sdk.to_managed_object(retval) + let i = 0; + for (let inv of get_investigations()) { + let new_quest_no = 942000 + i++; + investigation_id_map[new_quest_no] = inv + questManager._QuestDataDictionary[new_quest_no] = inv.quest_data + update_quest_no(inv.quest_data, new_quest_no) + list.Add(new_quest_no) + } + questManager._QuestDataDictionary + return retval + } +}); diff --git a/mod/Investigations/InvestigationData.ts b/mod/Investigations/InvestigationData.ts new file mode 100644 index 0000000..3474ad5 --- /dev/null +++ b/mod/Investigations/InvestigationData.ts @@ -0,0 +1,4627 @@ +type EnemyData = { + "_RouteNo": number, + "_PartsTbl": number, + "_InitSetName": string + "_SubType": number, + "_VitalTbl": number, + "_AttackTbl": number, + "_OtherTbl": number, + "_StaminaTbl": number, + "_Scale": number, + "_ScaleTbl": number, + "_Difficulty": number, + "_BossMulti": number, + "_IndividualType": number, + "__QuestName": string +} +export interface MonsterData { + Id: number, + Name: string, + MapIds: number[], + QuestType: number[], + OrderType: number, + QuestLevel: number, + TargetTypes: number[], + EnemyDataList: { + "0": EnemyData[], + "1": EnemyData[], + } + Icon: number +} + + +interface InvestigationData { + Monsters: { + [id: string]: MonsterData + } + + Maps: { + [id: string]: { + EmsSetNo: number[] + } + } +} + + +export let Data: InvestigationData = { + "Monsters": { + "0": { + "Id": 0, + "Name": "None", + "MapIds": [], + "QuestType": [], + "TargetTypes": [], + "OrderType": 99, + "QuestLevel": 10, + "EnemyDataList": { + "0": [], + "1": [] + }, + "Icon": 999 + }, + "1": { + "Id": 1, + "Name": "Rathian", + "MapIds": [ + 3, + 2, + 5, + 1, + 12 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 1, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 110, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "The Queen's Garden" + }, + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 110, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Rathian" + }, + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 110, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "An Audience With the Queen" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 183, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 152, + "_AttackTbl": 126, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 18, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Rathian" + } + ] + }, + "Icon": 0 + }, + "2": { + "Id": 2, + "Name": "Rathalos", + "MapIds": [ + 1, + 5, + 13 + ], + "QuestType": [ + 1 + ], + "TargetTypes": [ + 2 + ], + "OrderType": 16, + "QuestLevel": 3, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 116, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "King of the Crumbling Castle" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 116, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Rathalos" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 116, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Not Your Average Picnic" + } + ], + "1": [] + }, + "Icon": 1 + }, + "3": { + "Id": 3, + "Name": "Khezu", + "MapIds": [ + 4, + 5 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 1, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 110, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 17, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "The Alabaster Devourer" + }, + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 94, + "_AttackTbl": 111, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 123, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "In Pursuit of the Khezuit" + }, + { + "_RouteNo": 11, + "_PartsTbl": 128, + "_InitSetName": "2\u982d", + "_SubType": 0, + "_VitalTbl": 91, + "_AttackTbl": 111, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 90, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "In Pursuit of the Khezuit" + }, + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 110, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 17, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Khezu" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 182, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 144, + "_AttackTbl": 124, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 17, + "_Difficulty": 1, + "_BossMulti": 16, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Khezu" + } + ] + }, + "Icon": 2 + }, + "4": { + "Id": 4, + "Name": "Basarios", + "MapIds": [ + 2, + 5 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 1, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 110, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Pent-Up Frustrations" + }, + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 97, + "_AttackTbl": 115, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 123, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Double Basarios" + }, + { + "_RouteNo": 11, + "_PartsTbl": 133, + "_InitSetName": "2\u982d", + "_SubType": 0, + "_VitalTbl": 94, + "_AttackTbl": 115, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 90, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Double Basarios" + }, + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 97, + "_AttackTbl": 115, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 123, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Basarios Buzzkill" + }, + { + "_RouteNo": 11, + "_PartsTbl": 133, + "_InitSetName": "2\u982d", + "_SubType": 0, + "_VitalTbl": 94, + "_AttackTbl": 115, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 90, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Basarios Buzzkill" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 182, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 141, + "_AttackTbl": 124, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 16, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Basarios" + } + ] + }, + "Icon": 3 + }, + "7": { + "Id": 7, + "Name": "Diablos", + "MapIds": [ + 2 + ], + "QuestType": [ + 1 + ], + "TargetTypes": [ + 2 + ], + "OrderType": 16, + "QuestLevel": 3, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 116, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Dust Devil Despot" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 102, + "_AttackTbl": 117, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 123, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Monju Mashup!" + }, + { + "_RouteNo": 11, + "_PartsTbl": 137, + "_InitSetName": "2\u982d", + "_SubType": 0, + "_VitalTbl": 98, + "_AttackTbl": 117, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 90, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Monju Mashup!" + } + ], + "1": [] + }, + "Icon": 4 + }, + "19": { + "Id": 19, + "Name": "Daimyo Hermitaur", + "MapIds": [ + 1, + 12, + 2, + 3 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 7, + "QuestLevel": 0, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 110, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 102, + "_AttackTbl": 98, + "_OtherTbl": 130, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Uninvited Guest" + }, + { + "_RouteNo": 10, + "_PartsTbl": 120, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 89, + "_AttackTbl": 103, + "_OtherTbl": 130, + "_StaminaTbl": 3, + "_Scale": 123, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Supply Line Shell Game" + }, + { + "_RouteNo": 11, + "_PartsTbl": 120, + "_InitSetName": "2\u982d", + "_SubType": 0, + "_VitalTbl": 87, + "_AttackTbl": 103, + "_OtherTbl": 130, + "_StaminaTbl": 3, + "_Scale": 90, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Supply Line Shell Game" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 182, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 150, + "_AttackTbl": 126, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 16, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Daimyo Hermitaur" + } + ] + }, + "Icon": 43 + }, + "20": { + "Id": 20, + "Name": "Shogun Ceanataur", + "MapIds": [ + 3, + 5 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 2, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 112, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "My Ceanataur Gently Weeps" + }, + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 112, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Shogun Ceanataur" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 183, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 147, + "_AttackTbl": 125, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 18, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Shogun Ceanataur" + } + ] + }, + "Icon": 44 + }, + "23": { + "Id": 23, + "Name": "Rajang", + "MapIds": [ + 3, + 2, + 1, + 5, + 4, + 12, + 13 + ], + "QuestType": [ + 1 + ], + "TargetTypes": [ + 2 + ], + "OrderType": 16, + "QuestLevel": 4, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 129, + "_AttackTbl": 122, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Settle the Score!" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 118, + "_AttackTbl": 124, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 123, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "The Ultimate Fight?" + }, + { + "_RouteNo": 11, + "_PartsTbl": 149, + "_InitSetName": "2\u982d", + "_SubType": 0, + "_VitalTbl": 116, + "_AttackTbl": 124, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 97, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "The Ultimate Fight?" + }, + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 129, + "_AttackTbl": 122, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Rajang" + }, + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 129, + "_AttackTbl": 122, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Grabbin' Life by the Horns" + } + ], + "1": [] + }, + "Icon": 5 + }, + "24": { + "Id": 24, + "Name": "Kushala Daora", + "MapIds": [ + 4, + 2, + 13, + 12 + ], + "QuestType": [ + 2 + ], + "TargetTypes": [ + 3 + ], + "OrderType": 16, + "QuestLevel": 4, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 129, + "_AttackTbl": 122, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Storm of The Kushala Daora" + }, + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 129, + "_AttackTbl": 122, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "The Frozen Dictator" + }, + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 129, + "_AttackTbl": 122, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Kushala Daora" + }, + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 129, + "_AttackTbl": 122, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "A Cold Wind Blows" + } + ], + "1": [] + }, + "Icon": 6 + }, + "25": { + "Id": 25, + "Name": "Chameleos", + "MapIds": [ + 1, + 3, + 12, + 13 + ], + "QuestType": [ + 2 + ], + "TargetTypes": [ + 3 + ], + "OrderType": 16, + "QuestLevel": 4, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 129, + "_AttackTbl": 122, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Beyond the Silence" + }, + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 129, + "_AttackTbl": 122, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Leave No Trace Behind" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 134, + "_AttackTbl": 123, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Chameleos" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 134, + "_AttackTbl": 123, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Invisible Threat" + } + ], + "1": [] + }, + "Icon": 7 + }, + "27": { + "Id": 27, + "Name": "Teostra", + "MapIds": [ + 5, + 2, + 13 + ], + "QuestType": [ + 2 + ], + "TargetTypes": [ + 3 + ], + "OrderType": 16, + "QuestLevel": 4, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 129, + "_AttackTbl": 122, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Emperor of Flame" + }, + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 129, + "_AttackTbl": 122, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Burn Brighter Than the Sun" + }, + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 129, + "_AttackTbl": 122, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Teostra" + }, + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 129, + "_AttackTbl": 122, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "The Fire Still Burns" + } + ], + "1": [] + }, + "Icon": 8 + }, + "32": { + "Id": 32, + "Name": "Tigrex", + "MapIds": [ + 4, + 5, + 2, + 13 + ], + "QuestType": [ + 1 + ], + "TargetTypes": [ + 2 + ], + "OrderType": 16, + "QuestLevel": 3, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Absolute Power" + }, + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 109, + "_AttackTbl": 123, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 123, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Seismic Scares" + }, + { + "_RouteNo": 11, + "_PartsTbl": 141, + "_InitSetName": "2\u982d", + "_SubType": 0, + "_VitalTbl": 104, + "_AttackTbl": 123, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 90, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Seismic Scares" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Tigrex" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Destructive Instructor" + } + ], + "1": [] + }, + "Icon": 9 + }, + "37": { + "Id": 37, + "Name": "Nargacuga", + "MapIds": [ + 1, + 3, + 12 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 2, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 114, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Shadow in the Jungle" + }, + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 97, + "_AttackTbl": 115, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 123, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Shady Activity" + }, + { + "_RouteNo": 12, + "_PartsTbl": 133, + "_InitSetName": "2\u982d", + "_SubType": 0, + "_VitalTbl": 94, + "_AttackTbl": 115, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 90, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Shady Activity" + }, + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 114, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Nargacuga" + }, + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 114, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Into the Jungle Deep" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 184, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 146, + "_AttackTbl": 126, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 18, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Nargacuga" + } + ] + }, + "Icon": 10 + }, + "42": { + "Id": 42, + "Name": "Barioth", + "MapIds": [ + 4, + 13 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 2, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 114, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "White Knight on Ice" + }, + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 114, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Barioth" + }, + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 114, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "White Knight Vs. New Knight" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 184, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 147, + "_AttackTbl": 126, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 18, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Barioth" + } + ] + }, + "Icon": 11 + }, + "44": { + "Id": 44, + "Name": "Barroth", + "MapIds": [ + 2 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 0, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 120, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 107, + "_AttackTbl": 102, + "_OtherTbl": 130, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Barroth to a Great Start" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 182, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 145, + "_AttackTbl": 126, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 16, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Barroth" + } + ] + }, + "Icon": 12 + }, + "47": { + "Id": 47, + "Name": "Royal Ludroth", + "MapIds": [ + 3, + 5, + 12 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 0, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 120, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 107, + "_AttackTbl": 102, + "_OtherTbl": 130, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "You Had Me at Poofy" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 182, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 144, + "_AttackTbl": 126, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 16, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Royal Ludroth" + } + ] + }, + "Icon": 13 + }, + "54": { + "Id": 54, + "Name": "Great Baggi", + "MapIds": [ + 4 + ], + "QuestType": [ + 2 + ], + "TargetTypes": [ + 3 + ], + "OrderType": 22, + "QuestLevel": 5, + "EnemyDataList": { + "0": [], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 181, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 154, + "_AttackTbl": 125, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 16, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Great Baggi" + } + ] + }, + "Icon": 14 + }, + "57": { + "Id": 57, + "Name": "Zinogre", + "MapIds": [ + 3, + 1, + 12, + 13 + ], + "QuestType": [ + 1 + ], + "TargetTypes": [ + 2 + ], + "OrderType": 16, + "QuestLevel": 3, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Sacrilegious Thunder Wolf" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 102, + "_AttackTbl": 119, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 123, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Twin Sparks in the Dark" + }, + { + "_RouteNo": 11, + "_PartsTbl": 137, + "_InitSetName": "2\u982d", + "_SubType": 0, + "_VitalTbl": 98, + "_AttackTbl": 119, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 90, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Twin Sparks in the Dark" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Zinogre" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "An Ace Idea!" + } + ], + "1": [] + }, + "Icon": 15 + }, + "59": { + "Id": 59, + "Name": "Great Wroggi", + "MapIds": [ + 1, + 3, + 5, + 12 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 0, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 92, + "_AttackTbl": 103, + "_OtherTbl": 130, + "_StaminaTbl": 3, + "_Scale": 123, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "[REDACTED]" + }, + { + "_RouteNo": 11, + "_PartsTbl": 128, + "_InitSetName": "2\u982d", + "_SubType": 0, + "_VitalTbl": 87, + "_AttackTbl": 103, + "_OtherTbl": 130, + "_StaminaTbl": 3, + "_Scale": 90, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "[REDACTED]" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 181, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 154, + "_AttackTbl": 125, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 16, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Great Wroggi" + } + ] + }, + "Icon": 16 + }, + "60": { + "Id": 60, + "Name": "Arzuros", + "MapIds": [ + 1, + 3, + 13 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 0, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 92, + "_AttackTbl": 103, + "_OtherTbl": 130, + "_StaminaTbl": 3, + "_Scale": 123, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Catnap Ruined" + }, + { + "_RouteNo": 11, + "_PartsTbl": 128, + "_InitSetName": "2\u982d", + "_SubType": 0, + "_VitalTbl": 87, + "_AttackTbl": 103, + "_OtherTbl": 130, + "_StaminaTbl": 3, + "_Scale": 90, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Catnap Ruined" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 181, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 145, + "_AttackTbl": 123, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 16, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Arzuros" + } + ] + }, + "Icon": 17 + }, + "61": { + "Id": 61, + "Name": "Lagombi", + "MapIds": [ + 4, + 13 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 0, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 120, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 107, + "_AttackTbl": 102, + "_OtherTbl": 130, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "The Good, the Bad, and Lagombi" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 181, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 144, + "_AttackTbl": 125, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 16, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Lagombi" + } + ] + }, + "Icon": 18 + }, + "62": { + "Id": 62, + "Name": "Volvidon", + "MapIds": [ + 2, + 5, + 13 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 0, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 120, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 107, + "_AttackTbl": 102, + "_OtherTbl": 130, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "The Red Rolling Terror" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 181, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 139, + "_AttackTbl": 123, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 16, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Volvidon" + } + ] + }, + "Icon": 19 + }, + "71": { + "Id": 71, + "Name": "Gore Magala", + "MapIds": [ + 13, + 12, + 1, + 3 + ], + "QuestType": [ + 1 + ], + "TargetTypes": [ + 2 + ], + "OrderType": 16, + "QuestLevel": 3, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Dark Wings, Dark Work" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Gore Magala" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Unknown Invader" + } + ], + "1": [] + }, + "Icon": 47 + }, + "72": { + "Id": 72, + "Name": "Shagaru Magala", + "MapIds": [ + 13 + ], + "QuestType": [ + 2 + ], + "TargetTypes": [ + 3 + ], + "OrderType": 16, + "QuestLevel": 4, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 129, + "_AttackTbl": 122, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Dark Citadel, White Wheel" + } + ], + "1": [] + }, + "Icon": 48 + }, + "77": { + "Id": 77, + "Name": "Seregios", + "MapIds": [ + 2, + 1, + 13 + ], + "QuestType": [ + 1 + ], + "TargetTypes": [ + 2 + ], + "OrderType": 16, + "QuestLevel": 3, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "A Thousand Scales of Dread" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Seregios" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Dust off Those Hunting Boots" + } + ], + "1": [] + }, + "Icon": 49 + }, + "81": { + "Id": 81, + "Name": "Astalos", + "MapIds": [ + 1, + 3, + 12 + ], + "QuestType": [ + 1 + ], + "TargetTypes": [ + 2 + ], + "OrderType": 16, + "QuestLevel": 3, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 116, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "In Search of the Doctor" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 116, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Astalos" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 116, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Rumbling Tummy, Rumbling Thunder" + } + ], + "1": [] + }, + "Icon": 50 + }, + "82": { + "Id": 82, + "Name": "Mizutsune", + "MapIds": [ + 3, + 4, + 1, + 12 + ], + "QuestType": [ + 1 + ], + "TargetTypes": [ + 2 + ], + "OrderType": 16, + "QuestLevel": 3, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "A Mizutsune's Appeal" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Mizutsune" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Cherry Blossoms in Battle" + } + ], + "1": [] + }, + "Icon": 20 + }, + "89": { + "Id": 89, + "Name": "Magnamalo", + "MapIds": [ + 5, + 1, + 4 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 2, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 112, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Purging Hatred" + }, + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 112, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Magnamalo" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 118, + "_AttackTbl": 122, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 123, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Double Magnamalo" + }, + { + "_RouteNo": 11, + "_PartsTbl": 149, + "_InitSetName": "2\u982d", + "_SubType": 0, + "_VitalTbl": 116, + "_AttackTbl": 122, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 90, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Double Magnamalo" + }, + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 112, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Enshrined Resentment" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 118, + "_AttackTbl": 122, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 123, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Lava Caverns Litter Box" + }, + { + "_RouteNo": 11, + "_PartsTbl": 149, + "_InitSetName": "2\u982d", + "_SubType": 0, + "_VitalTbl": 116, + "_AttackTbl": 122, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 90, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Lava Caverns Litter Box" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 184, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 146, + "_AttackTbl": 125, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 18, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Magnamalo" + } + ] + }, + "Icon": 22 + }, + "90": { + "Id": 90, + "Name": "Bishaten", + "MapIds": [ + 3, + 1, + 12 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 1, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 110, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 17, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Sour Grapes" + }, + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 110, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 17, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Bishaten" + }, + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 110, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 17, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Fruit Vs. Firearms" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 182, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 143, + "_AttackTbl": 126, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 17, + "_Difficulty": 1, + "_BossMulti": 16, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Bishaten" + } + ] + }, + "Icon": 23 + }, + "91": { + "Id": 91, + "Name": "Aknosom", + "MapIds": [ + 1, + 4, + 12 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 0, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 120, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 107, + "_AttackTbl": 102, + "_OtherTbl": 130, + "_StaminaTbl": 3, + "_Scale": 85, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "It Could be Worse..." + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 182, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 143, + "_AttackTbl": 126, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 85, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 16, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Aknosom" + } + ] + }, + "Icon": 24 + }, + "92": { + "Id": 92, + "Name": "Tetranadon", + "MapIds": [ + 1, + 4, + 5, + 12 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 0, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 120, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 104, + "_AttackTbl": 102, + "_OtherTbl": 130, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Tetranadon Blockade" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 182, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 142, + "_AttackTbl": 126, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 16, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Tetranadon" + } + ] + }, + "Icon": 25 + }, + "93": { + "Id": 93, + "Name": "Somnacanth", + "MapIds": [ + 3, + 4, + 5 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 1, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 110, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Somnacanth Sleep Aid" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 183, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 146, + "_AttackTbl": 126, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 18, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Somnacanth" + } + ] + }, + "Icon": 26 + }, + "94": { + "Id": 94, + "Name": "Rakna-Kadaki", + "MapIds": [ + 5, + 2 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 2, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 114, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "A Sandy Spider Nest" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 184, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 146, + "_AttackTbl": 126, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 18, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Rakna-Kadaki" + } + ] + }, + "Icon": 27, + }, + "95": { + "Id": 95, + "Name": "Almudron", + "MapIds": [ + 3, + 2, + 1 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 2, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 114, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Trial of the Almudron" + }, + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 114, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Almudron" + }, + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 114, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "A Muddy Revival" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 184, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 147, + "_AttackTbl": 126, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 18, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Almudron" + } + ] + }, + "Icon": 28 + }, + "96": { + "Id": 96, + "Name": "Wind Serpent Ibushi", + "MapIds": [], + "QuestType": [], + "TargetTypes": [], + "OrderType": 99, + "QuestLevel": 10, + "EnemyDataList": { + "0": [], + "1": [] + }, + "Icon": 29 + }, + "97": { + "Id": 97, + "Name": "Goss Harag", + "MapIds": [ + 4, + 13 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 2, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 111, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Oh, My Garsh Harag" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 184, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 146, + "_AttackTbl": 125, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 18, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Goss Harag" + } + ] + }, + "Icon": 30 + }, + "98": { + "Id": 98, + "Name": "Great Izuchi", + "MapIds": [ + 4, + 1 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 0, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 102, + "_OtherTbl": 130, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Reap What You Saw" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 181, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 154, + "_AttackTbl": 125, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 16, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Great Izuchi" + } + ] + }, + "Icon": 31 + }, + "99": { + "Id": 99, + "Name": "Thunder Serpent Narwa", + "MapIds": [], + "QuestType": [], + "TargetTypes": [], + "OrderType": 99, + "QuestLevel": 10, + "EnemyDataList": { + "0": [], + "1": [] + }, + "Icon": 32 + }, + "100": { + "Id": 100, + "Name": "Anjanath", + "MapIds": [ + 2, + 5, + 3, + 1, + 12, + 13 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 1, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 107, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Provoking an Anjanath's Wrath" + }, + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 107, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Anjanath" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 183, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 147, + "_AttackTbl": 126, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 18, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Anjanath" + } + ] + }, + "Icon": 33 + }, + "102": { + "Id": 102, + "Name": "Pukei-Pukei", + "MapIds": [ + 2, + 3, + 1 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 1, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 110, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Poison Drops in the Sand" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 183, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 152, + "_AttackTbl": 126, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 18, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Pukei-Pukei" + } + ] + }, + "Icon": 34 + }, + "107": { + "Id": 107, + "Name": "Kulu-Ya-Ku", + "MapIds": [ + 1, + 2, + 3, + 5, + 12 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 0, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 102, + "_OtherTbl": 130, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Need a Hunter, ASAP!" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 181, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 150, + "_AttackTbl": 125, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 16, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Kulu-Ya-Ku" + } + ] + }, + "Icon": 35 + }, + "108": { + "Id": 108, + "Name": "Jyuratodus", + "MapIds": [ + 3 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 1, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 117, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Messed Up Situation" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 183, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 146, + "_AttackTbl": 132, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 18, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Jyuratodus" + } + ] + }, + "Icon": 36 + }, + "109": { + "Id": 109, + "Name": "Tobi-Kadachi", + "MapIds": [ + 3, + 1, + 12 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 1, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 108, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Rumble in the Jungle" + }, + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 108, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Tobi-Kadachi" + }, + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 108, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Flicker in the Night" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 183, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 146, + "_AttackTbl": 126, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 18, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Tobi-Kadachi" + } + ] + }, + "Icon": 37 + }, + "118": { + "Id": 118, + "Name": "Bazelgeuse", + "MapIds": [ + 1, + 4, + 3, + 2, + 5, + 13, + 12 + ], + "QuestType": [ + 1 + ], + "TargetTypes": [ + 2 + ], + "OrderType": 16, + "QuestLevel": 4, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 129, + "_AttackTbl": 122, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Bazelgeuse Warning" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 118, + "_AttackTbl": 124, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 123, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Bested by Bazelgeuse" + }, + { + "_RouteNo": 11, + "_PartsTbl": 149, + "_InitSetName": "2\u982d", + "_SubType": 0, + "_VitalTbl": 116, + "_AttackTbl": 124, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 90, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Bested by Bazelgeuse" + }, + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 129, + "_AttackTbl": 122, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Bazelgeuse" + }, + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 129, + "_AttackTbl": 122, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Fire Vs. Fire" + } + ], + "1": [] + }, + "Icon": 38 + }, + "132": { + "Id": 132, + "Name": "Malzeno", + "MapIds": [ + 13, + 1 + ], + "QuestType": [ + 2 + ], + "TargetTypes": [ + 3 + ], + "OrderType": 16, + "QuestLevel": 4, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 129, + "_AttackTbl": 122, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Crimson Moonlight" + }, + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 129, + "_AttackTbl": 122, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Witness by Moonlight" + } + ], + "1": [] + }, + "Icon": 58 + }, + "133": { + "Id": 133, + "Name": "Lunagaron", + "MapIds": [ + 13, + 1, + 4, + 12 + ], + "QuestType": [ + 1 + ], + "TargetTypes": [ + 2 + ], + "OrderType": 16, + "QuestLevel": 3, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Howling Moon" + }, + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "8", + "_SubType": 1, + "_VitalTbl": 115, + "_AttackTbl": 122, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Gathering of the Qurio" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Ice Wolf, Red Moon" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Lunagaron" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Breaking the Ice" + } + ], + "1": [] + }, + "Icon": 59 + }, + "134": { + "Id": 134, + "Name": "Garangolm", + "MapIds": [ + 13, + 3 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 2, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 114, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 2, + "_BossMulti": 17, + "_IndividualType": 0, + "__QuestName": "Garangolm Gone Mad" + }, + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 114, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 2, + "_BossMulti": 17, + "_IndividualType": 0, + "__QuestName": "A Rocky Rampage" + }, + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 114, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 2, + "_BossMulti": 17, + "_IndividualType": 0, + "__QuestName": "Operation Garangolm" + }, + { + "_RouteNo": 10, + "_PartsTbl": 141, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 109, + "_AttackTbl": 123, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 117, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 17, + "_IndividualType": 0, + "__QuestName": "Operation Double Garangolm" + }, + { + "_RouteNo": 11, + "_PartsTbl": 141, + "_InitSetName": "2\u982d", + "_SubType": 0, + "_VitalTbl": 104, + "_AttackTbl": 123, + "_OtherTbl": 136, + "_StaminaTbl": 3, + "_Scale": 90, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 17, + "_IndividualType": 0, + "__QuestName": "Operation Double Garangolm" + }, + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 114, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 2, + "_BossMulti": 17, + "_IndividualType": 0, + "__QuestName": "A Tough Lesson" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 184, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 147, + "_AttackTbl": 126, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 1, + "_BossMulti": 19, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Garangolm" + } + ] + }, + "Icon": 60 + }, + "135": { + "Id": 135, + "Name": "Gaismagorm", + "MapIds": [], + "QuestType": [], + "TargetTypes": [], + "OrderType": 99, + "QuestLevel": 10, + "EnemyDataList": { + "0": [], + "1": [] + }, + "Icon": 61 + }, + "136": { + "Id": 136, + "Name": "Espinas", + "MapIds": [ + 12, + 13 + ], + "QuestType": [ + 1 + ], + "TargetTypes": [ + 2 + ], + "OrderType": 16, + "QuestLevel": 3, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 1, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "A Slumbering Jungle Espinas" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 1, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Espinas" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 1, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Moonlit Espinascapade" + } + ], + "1": [] + }, + "Icon": 62 + }, + "346": { + "Id": 346, + "Name": "Blood Orange Bishaten", + "MapIds": [ + 2, + 1, + 13 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 1, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 110, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 17, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "The Assault of the Scarlet Tengu" + }, + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 94, + "_AttackTbl": 111, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 114, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Pinecone Pelting Panic" + }, + { + "_RouteNo": 11, + "_PartsTbl": 128, + "_InitSetName": "2\u982d", + "_SubType": 0, + "_VitalTbl": 91, + "_AttackTbl": 111, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 90, + "_ScaleTbl": 0, + "_Difficulty": 0, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Pinecone Pelting Panic" + }, + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 110, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 17, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Scarlet Tengu in the Shrine Ruins" + }, + { + "_RouteNo": 10, + "_PartsTbl": 128, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 115, + "_AttackTbl": 110, + "_OtherTbl": 131, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 17, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Blood Orange Bishaten" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 183, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 146, + "_AttackTbl": 126, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 17, + "_Difficulty": 1, + "_BossMulti": 18, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Blood Orange Bishaten" + } + ] + }, + "Icon": 53 + }, + "349": { + "Id": 349, + "Name": "Aurora Somnacanth", + "MapIds": [ + 4, + 13 + ], + "QuestType": [ + 1, + 2 + ], + "TargetTypes": [ + 2, + 3 + ], + "OrderType": 16, + "QuestLevel": 2, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 114, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Keep it Busy" + }, + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 114, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Aurora Somnacanth" + }, + { + "_RouteNo": 10, + "_PartsTbl": 133, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 119, + "_AttackTbl": 114, + "_OtherTbl": 132, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Passion Melts Ice" + } + ], + "1": [ + { + "_RouteNo": 10, + "_PartsTbl": 184, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 146, + "_AttackTbl": 126, + "_OtherTbl": 153, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 1, + "_BossMulti": 18, + "_IndividualType": 1, + "__QuestName": "Anomaly Research: Aurora Somnacanth" + } + ] + }, + "Icon": 54 + }, + "350": { + "Id": 350, + "Name": "Pyre Rakna-Kadaki", + "MapIds": [ + 5, + 13 + ], + "QuestType": [ + 1 + ], + "TargetTypes": [ + 2 + ], + "OrderType": 16, + "QuestLevel": 3, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "A Mighty Need" + }, + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Pyre Rakna-Kadaki" + } + ], + "1": [] + }, + "Icon": 55 + }, + "351": { + "Id": 351, + "Name": "Magma Almudron", + "MapIds": [ + 5 + ], + "QuestType": [ + 1 + ], + "TargetTypes": [ + 2 + ], + "OrderType": 16, + "QuestLevel": 3, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 137, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 123, + "_AttackTbl": 118, + "_OtherTbl": 135, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 6, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Hot Mud in Your Eye" + } + ], + "1": [] + }, + "Icon": 56 + }, + "1303": { + "Id": 1303, + "Name": "Furious Rajang", + "MapIds": [ + 4, + 1, + 2, + 12, + 3, + 13, + 5 + ], + "QuestType": [ + 1 + ], + "TargetTypes": [ + 2 + ], + "OrderType": 22, + "QuestLevel": 5, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 153, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 138, + "_AttackTbl": 127, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Pierce the Heavens" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 134, + "_AttackTbl": 123, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Unreasonable Rage" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 134, + "_AttackTbl": 123, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Unreasonable Rage" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 134, + "_AttackTbl": 123, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Unreasonable Rage" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 134, + "_AttackTbl": 123, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Unreasonable Rage" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 134, + "_AttackTbl": 123, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Unreasonable Rage" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 134, + "_AttackTbl": 123, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Unreasonable Rage" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 134, + "_AttackTbl": 123, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Furious Golden Fur" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 134, + "_AttackTbl": 123, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 11, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Rage That Never Dies" + } + ], + "1": [] + }, + "Icon": 45 + }, + "1366": { + "Id": 1366, + "Name": "Crimson Glow Valstrax", + "MapIds": [ + 1, + 4, + 5, + 2, + 3, + 13, + 12 + ], + "QuestType": [ + 2 + ], + "TargetTypes": [ + 3 + ], + "OrderType": 22, + "QuestLevel": 5, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 153, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 138, + "_AttackTbl": 123, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Star at Worlds End" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 134, + "_AttackTbl": 123, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Mysterious Glow" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 134, + "_AttackTbl": 123, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Mysterious Glow" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 134, + "_AttackTbl": 123, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Mysterious Glow" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 134, + "_AttackTbl": 123, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Mysterious Glow" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 134, + "_AttackTbl": 123, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Mysterious Glow" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 134, + "_AttackTbl": 123, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Mysterious Glow" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 134, + "_AttackTbl": 123, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Jungle Comet" + } + ], + "1": [] + }, + "Icon": 21 + }, + "1369": { + "Id": 1369, + "Name": "Scorned Magnamalo", + "MapIds": [ + 13, + 1 + ], + "QuestType": [ + 1 + ], + "TargetTypes": [ + 2 + ], + "OrderType": 22, + "QuestLevel": 5, + "EnemyDataList": { + "0": [ + { + "_RouteNo": 10, + "_PartsTbl": 153, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 138, + "_AttackTbl": 130, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Back with a Vengeance" + }, + { + "_RouteNo": 10, + "_PartsTbl": 149, + "_InitSetName": "\u30e1\u30a4\u30f3", + "_SubType": 0, + "_VitalTbl": 134, + "_AttackTbl": 123, + "_OtherTbl": 137, + "_StaminaTbl": 3, + "_Scale": 100, + "_ScaleTbl": 20, + "_Difficulty": 2, + "_BossMulti": 16, + "_IndividualType": 0, + "__QuestName": "Operation Wrath" + } + ], + "1": [] + }, + "Icon": 52 + }, + "1379": { + "Id": 1379, + "Name": "Narwa the Allmother", + "MapIds": [], + "QuestType": [], + "TargetTypes": [], + "OrderType": 99, + "QuestLevel": 10, + "EnemyDataList": { + "0": [], + "1": [] + }, + "Icon": 40 + }, + "1793": { + "Id": 1793, + "Name": "Apex Rathian", + "MapIds": [ + 3, + 1, + 5 + ], + "QuestType": [], + "TargetTypes": [], + "OrderType": 99, + "QuestLevel": 10, + "EnemyDataList": { + "0": [], + "1": [] + }, + "Icon": 65 + }, + "1794": { + "Id": 1794, + "Name": "Apex Rathalos", + "MapIds": [ + 5, + 1 + ], + "QuestType": [], + "TargetTypes": [], + "OrderType": 99, + "QuestLevel": 10, + "EnemyDataList": { + "0": [], + "1": [] + }, + "Icon": 66 + }, + "1799": { + "Id": 1799, + "Name": "Apex Diablos", + "MapIds": [ + 2 + ], + "QuestType": [], + "TargetTypes": [], + "OrderType": 99, + "QuestLevel": 10, + "EnemyDataList": { + "0": [], + "1": [] + }, + "Icon": 67 + }, + "1849": { + "Id": 1849, + "Name": "Apex Zinogre", + "MapIds": [ + 1, + 3 + ], + "QuestType": [], + "TargetTypes": [], + "OrderType": 99, + "QuestLevel": 10, + "EnemyDataList": { + "0": [], + "1": [] + }, + "Icon": 68 + }, + "1852": { + "Id": 1852, + "Name": "Apex Arzuros", + "MapIds": [ + 1, + 3 + ], + "QuestType": [], + "TargetTypes": [], + "OrderType": 99, + "QuestLevel": 10, + "EnemyDataList": { + "0": [], + "1": [] + }, + "Icon": 69 + }, + "1874": { + "Id": 1874, + "Name": "Apex Mizutsune", + "MapIds": [ + 4, + 3, + 1 + ], + "QuestType": [], + "TargetTypes": [], + "OrderType": 99, + "QuestLevel": 10, + "EnemyDataList": { + "0": [], + "1": [] + }, + "Icon": 70 + } + }, + "Maps": { + "1": { + "EmsSetNo": [ + 2, + 1, + 29, + 0, + 23, + 30, + 24, + 25, + 3, + 26, + 35, + 36 + ] + }, + "2": { + "EmsSetNo": [ + 5, + 4, + 8, + 9, + 6, + 37, + 38, + 7 + ] + }, + "3": { + "EmsSetNo": [ + 11, + 10, + 13, + 14, + 12, + 39, + 41, + 40, + 42 + ] + }, + "4": { + "EmsSetNo": [ + 16, + 15, + 19, + 20, + 17, + 18 + ] + }, + "5": { + "EmsSetNo": [ + 22, + 21, + 31, + 43, + 45, + 44, + 27, + 28 + ] + }, + "12": { + "EmsSetNo": [ + 47, + 33, + 48, + 46 + ] + }, + "13": { + "EmsSetNo": [ + 34, + 50, + 49, + 0 + ] + } + } +} \ No newline at end of file diff --git a/mod/Investigations/QuestGenerator.ts b/mod/Investigations/QuestGenerator.ts index fc98ca8..0373e9b 100644 --- a/mod/Investigations/QuestGenerator.ts +++ b/mod/Investigations/QuestGenerator.ts @@ -1,4 +1,9 @@ -import { create_array } from "./Utilities"; +import { snow } from "Investigations/IL2CPP"; +import { create_array } from "Investigations/Utilities"; +import { Data, MonsterData } from "Investigations/InvestigationData"; +import { Investigation } from "Investigations/Investigation"; + +import QuestOrderType = snow.quest.QuestOrderType; let QuestData = sdk.find_type_definition("snow.quest.QuestData"); let NormalQuestData = sdk.find_type_definition( @@ -25,10 +30,11 @@ function create_base_quest_data() { normal_quest_data._TimeLimit = 50; normal_quest_data._QuestLife = 3; // carts - normal_quest_data._OrderType = create_array( - "snow.quest.QuestOrderType", - [0x10, 0] - ); // Starting conditions + normal_quest_data._OrderType = create_array("snow.quest.QuestOrderType", [ + QuestOrderType.M1, + QuestOrderType.None, + ]); // Starting conditions + normal_quest_data._TargetType = create_array( "snow.quest.QuestTargetType", [0, 0] @@ -156,7 +162,138 @@ function create_base_quest_data() { let quest_data = QuestData.create_instance(true); quest_data.set_RawNormal(normal_quest_data); quest_data.set_RawEnemy(enemy_quest_data); + return quest_data; +} + +let elder_dragons = [ + "Teostra", + "Kushala Daora", + "Chameleos", + "Malzeno", + "Shagaru Magal", +]; +function can_capture(monster_data: MonsterData) { + return elder_dragons.indexOf(monster_data.Name) >= 0; +} + +function set_quest_target( + quest_data: snow.quest.QuestData, + monster_id: number +) { + let monster_data = Data.Monsters[monster_id.toString()]; + if (!monster_data) { + return; + } + + if (monster_data.MapIds.length == 0) { + return; + } + + let normal_quest_data = quest_data.get_RawNormal(); + normal_quest_data._QuestType = snow.quest.QuestType.HUNTING; + normal_quest_data._TargetType[0] = snow.quest.QuestTargetType.Hunting; + if (!can_capture(monster_data)) { + (normal_quest_data._QuestType = snow.quest.QuestType.KILL), + (normal_quest_data._TargetType[0] = snow.quest.QuestTargetType.Kill); + } + + normal_quest_data._TgtEmType[0] = monster_data.Id; + normal_quest_data._TgtNum[0] = 1; + + normal_quest_data._BossEmType[0] = monster_data.Id; + normal_quest_data._BossSetCondition[0] = 1; + normal_quest_data._Icon[0] = monster_data.Icon; + normal_quest_data._QuestLv = monster_data.QuestLevel; + + let enemy_quest_data = quest_data.get_RawEnemy(); + for (let k in monster_data.EnemyDataList["0"][0]) { + if (k.startsWith("__")) { + continue; + } + enemy_quest_data[k][0] = monster_data.EnemyDataList["0"][0][k]; + } +} + +function set_extra( + quest_data: snow.quest.QuestData, + monster_id: number, + index: number +) { + let monster_data = Data.Monsters[monster_id.toString()]; + if (!monster_data) { + return; + } + + let normal = quest_data.get_RawNormal(); + normal._InitExtraEmNum += 1; + + normal._BossEmType[index] = monster_id; + normal._BossSetCondition[index] = 1; + + let enemy_quest_data = quest_data.get_RawEnemy(); + for (let k in monster_data.EnemyDataList["0"][0]) { + if (k.startsWith("__")) { + continue; + } + enemy_quest_data[k][0] = monster_data.EnemyDataList["0"][0][k]; + } +} + +function set_map(quest_data: snow.quest.QuestData, map_id: number) { + quest_data.get_RawNormal()._MapNo = map_id; + quest_data.get_RawEnemy()._EmsSetNo = + Data.Maps[map_id.toString()].EmsSetNo[0]; +} + +export function create_investigation(player_name: string, monster_id: number) { + let monster_data = Data.Monsters[monster_id]; + if (!monster_data || monster_data.MapIds.length > 0) { + return; + } + + math.randomseed(os.time(), player_name.length ^ string.byte(player_name)); + + let pickr = (t: any[]): any => { + return t[math.random(t.length) - 1]; + }; + + let map = pickr(monster_data.MapIds); + let monsters_in_map = Object.values(Data.Monsters) + .filter((m) => m.MapIds.indexOf(map) >= 0) + .map((m) => m.Id); + let investigation: Investigation = { + map, + target_monster: monster_id, + extra_monster: [pickr(monsters_in_map), pickr(monsters_in_map)], + pinned: false, + }; + return investigation; } -export function create_investigation() { -} \ No newline at end of file +let a: Investigation; + +export function generate_quest_data( + investigation: Investigation +): snow.quest.QuestData { + log.info( + `generating quest for investigation: ${json.dump_string(investigation)}` + ); + let quest_data = create_base_quest_data(); + set_map(quest_data, investigation.map); + set_quest_target(quest_data, investigation.target_monster); + set_extra(quest_data, investigation.extra_monster[0], 1); + set_extra(quest_data, investigation.extra_monster[1], 2); + return quest_data; +} + +export function update_quest_no( + quest_data: snow.quest.QuestData, + quest_no: number +) { + quest_data.get_RawNormal()._QuestNo = quest_no; + quest_data.get_RawEnemy()._QuestNo = quest_no; +} + +export function get_monster_name(monster_id: number): string { + return Data.Monsters[monster_id.toString()].Name; +} diff --git a/mod/Investigations/Utilities.ts b/mod/Investigations/Utilities.ts index c7d38e0..1729af8 100644 --- a/mod/Investigations/Utilities.ts +++ b/mod/Investigations/Utilities.ts @@ -1,13 +1,15 @@ -import { System } from "Investigations/IL2CPP/il2cpp"; +import { System } from "Investigations/IL2CPP"; -export function create_array( - type: string, - table: any[] -): System.Array.Generic; export function create_array( type: T, table: REType[] -): System.Array.Generic> { +): System.Array.Generic>; +export function create_array( + type: string, + table: any[] +): System.Array.Generic; + +export function create_array(type: string, table: any[]): System.Array.Generic { let array = sdk.create_managed_array(type, table.length); for (let i = 0; i < table.length; ++i) { array[i] = table[i]; diff --git a/mod/Investigations/dist/Investigations.lua b/mod/Investigations/dist/Investigations.lua new file mode 100644 index 0000000..7b9dc84 --- /dev/null +++ b/mod/Investigations/dist/Investigations.lua @@ -0,0 +1 @@ +require("Investigations.Investigation") diff --git a/mod/Investigations/tsconfig.json b/mod/Investigations/tsconfig.json index ff09a81..1770ef3 100644 --- a/mod/Investigations/tsconfig.json +++ b/mod/Investigations/tsconfig.json @@ -7,16 +7,13 @@ "types": [ "lua-types/5.4" ], - "incremental": true, "outDir": "./dist/Investigations", "baseUrl": ".", "paths": { - "Investigations/IL2CPP/*": [ - "../../IL2CPP/*" - ], "Investigations/*": [ + "../../IL2CPP/*", "./*" - ] + ], } }, "tstl": { From 80c4c287235622cdcea38655e6803cab6ddb0975 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Thu, 28 Jul 2022 11:03:46 +0200 Subject: [PATCH 05/39] Mod packaging --- package-mods.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 package-mods.py diff --git a/package-mods.py b/package-mods.py new file mode 100644 index 0000000..eb0d21f --- /dev/null +++ b/package-mods.py @@ -0,0 +1,26 @@ +import os +import shutil +from zipfile import ZipFile + +os.chdir(os.path.dirname(__file__)) + +def zipfolder(foldername: str, zip_path: str): + with ZipFile(zip_path, 'w') as zipfile: + for root, dirs, files in os.walk(foldername): + print(root, dirs, files) + for file in files: + filepath = os.path.join(root, file) + zipfile.write( + filepath, + os.path.join('reframework', "autorun", os.path.relpath( + filepath, + foldername + ))) + + +os.makedirs("output") +mod_dirs = next(os.walk("mod"))[1] +for m in mod_dirs: + name = os.path.basename(m) + shutil.copy(os.path.join("IL2CPP", "IL2CPP.lua"), os.path.join("mod", name, "dist", name)) + zipfolder(os.path.join("mod", name, "dist"), os.path.join("output", f"{name}.zip")) From 009541af262ebb10d45661d8c10182c4ee139cfe Mon Sep 17 00:00:00 2001 From: Strackeror Date: Thu, 28 Jul 2022 11:03:49 +0200 Subject: [PATCH 06/39] IL2CPP capitalization for real fix output dir creation --- package-mods.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-mods.py b/package-mods.py index eb0d21f..6ef3392 100644 --- a/package-mods.py +++ b/package-mods.py @@ -18,7 +18,7 @@ def zipfolder(foldername: str, zip_path: str): ))) -os.makedirs("output") +os.makedirs("output", exist_ok=True) mod_dirs = next(os.walk("mod"))[1] for m in mod_dirs: name = os.path.basename(m) From 495d711d48d6ade96d476c4a37f25e91e0ff3a29 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Thu, 28 Jul 2022 11:03:49 +0200 Subject: [PATCH 07/39] Fix stamina max parameter --- mod/ConvenientSpiribirds/ConvenientSpiribird.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/ConvenientSpiribirds/ConvenientSpiribird.ts b/mod/ConvenientSpiribirds/ConvenientSpiribird.ts index 16ebf44..7264a88 100644 --- a/mod/ConvenientSpiribirds/ConvenientSpiribird.ts +++ b/mod/ConvenientSpiribirds/ConvenientSpiribird.ts @@ -35,7 +35,7 @@ sdk.hook( let player = sdk.to_managed_object(self); let count = sdk.to_int64(cnt); - next_stamina_max = count * 30; + next_stamina_max = count * 30.0; next_player = player; }, From 99fac2943695f907d59e808cae61f342bc175aab Mon Sep 17 00:00:00 2001 From: Strackeror Date: Thu, 28 Jul 2022 13:55:14 +0200 Subject: [PATCH 08/39] Investigations: Stricter typechecking --- mod/Investigations/Investigation.ts | 33 +++++++++++-------- mod/Investigations/InvestigationData.ts | 2 +- mod/Investigations/QuestGenerator.ts | 42 ++++++++++++++----------- mod/Investigations/tsconfig.json | 3 +- 4 files changed, 47 insertions(+), 33 deletions(-) diff --git a/mod/Investigations/Investigation.ts b/mod/Investigations/Investigation.ts index 59a78bf..8e9d2f9 100644 --- a/mod/Investigations/Investigation.ts +++ b/mod/Investigations/Investigation.ts @@ -7,12 +7,14 @@ import { } from "Investigations/QuestGenerator"; import QCF = snow.gui.fsm.questcounter.GuiQuestCounterFsmManager; -export interface Investigation { +export interface InvestigationDef { map: number; target_monster: number; extra_monster: [number, number]; pinned: boolean; - quest_data?: snow.quest.QuestData; +} +export interface Investigation extends InvestigationDef { + quest_data: snow.quest.QuestData; } let current_investigation_data: { @@ -27,15 +29,14 @@ let investigation_id_map: { function get_investigations(): Investigation[] { const current_name = snow.SnowSaveService.M.Instance?.getCurrentHunterName(); if (!current_name) { - return; + return []; } if (current_investigation_data.current_player == current_name) { return current_investigation_data.investigations; } - current_investigation_data.investigations = json.load_file( - `Investigations/${current_name}.json` - ); + current_investigation_data.investigations = + json.load_file(`Investigations/${current_name}.json`) ?? []; for (let i of current_investigation_data.investigations) { i.quest_data = generate_quest_data(i); } @@ -53,7 +54,13 @@ function save_investigations() { ); } -let next_returned_text: string = undefined +function get_player_name(): string { + return ( + snow.SnowSaveService.M.Instance?.getCurrentHunterName() ?? "__Unknown__" + ); +} + +let next_returned_text: string | undefined = undefined sdk.hook( snow.quest.QuestData.M.getQuestTextCore, (args) => { @@ -98,15 +105,11 @@ sdk.hook(snow.QuestManager.M.questEnemyDie, ([_, self, mon]) => { if (quest_mgr.getQuestRank_Lv() != snow.QuestManager.QuestRank.Master) { return; } - quest_mgr._QuestDataDictionary; let monster = sdk.to_managed_object(mon); let monster_id = monster.get_EnemyType(); - if (snow.QuestManager.M.Instance.getQuestRank_Lv() != snow.QuestManager.QuestRank.Master) { - return - } - let inv = create_investigation(snow.SnowSaveService.M.Instance.getCurrentHunterName(), monster_id) + let inv = create_investigation(get_player_name(), monster_id) as Investigation if (!inv) { return } @@ -121,6 +124,10 @@ sdk.hook(snow.QuestManager.M.makeQuestNoList, undefined, (retval) => { snow.gui.fsm.questcounter.GuiQuestCounterFsmManager.M.Instance; let questManager = snow.QuestManager.M.Instance; + if (!questCounter || !questManager) { + return retval + } + if ( questCounter.getQuestCounterSelectedTopMenu() == QCF.QuestCounterTopMenuType.Normal_Hall_Master && @@ -139,6 +146,6 @@ sdk.hook(snow.QuestManager.M.makeQuestNoList, undefined, (retval) => { list.Add(new_quest_no) } questManager._QuestDataDictionary - return retval } + return retval }); diff --git a/mod/Investigations/InvestigationData.ts b/mod/Investigations/InvestigationData.ts index 3474ad5..fd0bafe 100644 --- a/mod/Investigations/InvestigationData.ts +++ b/mod/Investigations/InvestigationData.ts @@ -1,4 +1,4 @@ -type EnemyData = { +export type EnemyData = { "_RouteNo": number, "_PartsTbl": number, "_InitSetName": string diff --git a/mod/Investigations/QuestGenerator.ts b/mod/Investigations/QuestGenerator.ts index 0373e9b..90a206f 100644 --- a/mod/Investigations/QuestGenerator.ts +++ b/mod/Investigations/QuestGenerator.ts @@ -1,7 +1,7 @@ import { snow } from "Investigations/IL2CPP"; import { create_array } from "Investigations/Utilities"; -import { Data, MonsterData } from "Investigations/InvestigationData"; -import { Investigation } from "Investigations/Investigation"; +import { Data, EnemyData, MonsterData } from "Investigations/InvestigationData"; +import { Investigation, InvestigationDef } from "Investigations/Investigation"; import QuestOrderType = snow.quest.QuestOrderType; @@ -176,6 +176,22 @@ function can_capture(monster_data: MonsterData) { return elder_dragons.indexOf(monster_data.Name) >= 0; } +function set_enemy_data(quest_enemy_data: snow.quest.NormalQuestDataForEnemy.Param, enemy_data: EnemyData, index: number) { + quest_enemy_data._RouteNo[index] = enemy_data["_RouteNo"] + quest_enemy_data._PartsTbl[index] = enemy_data["_PartsTbl"] + quest_enemy_data._InitSetName[index] = enemy_data["_InitSetName"] + quest_enemy_data._SubType[index] = enemy_data["_SubType"] + quest_enemy_data._VitalTbl[index] = enemy_data["_VitalTbl"] + quest_enemy_data._AttackTbl[index] = enemy_data["_AttackTbl"] + quest_enemy_data._OtherTbl[index] = enemy_data["_OtherTbl"] + quest_enemy_data._StaminaTbl[index] = enemy_data["_StaminaTbl"] + quest_enemy_data._Scale[index] = enemy_data["_Scale"] + quest_enemy_data._ScaleTbl[index] = enemy_data["_ScaleTbl"] + quest_enemy_data._Difficulty[index] = enemy_data["_Difficulty"] + quest_enemy_data._BossMulti[index] = enemy_data["_BossMulti"] + quest_enemy_data._IndividualType[index] = enemy_data["_IndividualType"] +} + function set_quest_target( quest_data: snow.quest.QuestData, monster_id: number @@ -206,12 +222,8 @@ function set_quest_target( normal_quest_data._QuestLv = monster_data.QuestLevel; let enemy_quest_data = quest_data.get_RawEnemy(); - for (let k in monster_data.EnemyDataList["0"][0]) { - if (k.startsWith("__")) { - continue; - } - enemy_quest_data[k][0] = monster_data.EnemyDataList["0"][0][k]; - } + let enemy_data = monster_data.EnemyDataList["0"][0] + set_enemy_data(enemy_quest_data, enemy_data, 0) } function set_extra( @@ -231,12 +243,8 @@ function set_extra( normal._BossSetCondition[index] = 1; let enemy_quest_data = quest_data.get_RawEnemy(); - for (let k in monster_data.EnemyDataList["0"][0]) { - if (k.startsWith("__")) { - continue; - } - enemy_quest_data[k][0] = monster_data.EnemyDataList["0"][0][k]; - } + let enemy_data = monster_data.EnemyDataList["0"][0] + set_enemy_data(enemy_quest_data, enemy_data, index) } function set_map(quest_data: snow.quest.QuestData, map_id: number) { @@ -261,7 +269,7 @@ export function create_investigation(player_name: string, monster_id: number) { let monsters_in_map = Object.values(Data.Monsters) .filter((m) => m.MapIds.indexOf(map) >= 0) .map((m) => m.Id); - let investigation: Investigation = { + let investigation: InvestigationDef = { map, target_monster: monster_id, extra_monster: [pickr(monsters_in_map), pickr(monsters_in_map)], @@ -270,10 +278,8 @@ export function create_investigation(player_name: string, monster_id: number) { return investigation; } -let a: Investigation; - export function generate_quest_data( - investigation: Investigation + investigation: InvestigationDef, ): snow.quest.QuestData { log.info( `generating quest for investigation: ${json.dump_string(investigation)}` diff --git a/mod/Investigations/tsconfig.json b/mod/Investigations/tsconfig.json index 1770ef3..3c68caf 100644 --- a/mod/Investigations/tsconfig.json +++ b/mod/Investigations/tsconfig.json @@ -14,7 +14,8 @@ "../../IL2CPP/*", "./*" ], - } + }, + "strict": true, }, "tstl": { "luaLibImport": "inline", From 49998977ba05ea93ee87794b0b9206466b6ef63c Mon Sep 17 00:00:00 2001 From: Strackeror Date: Thu, 28 Jul 2022 18:04:12 +0200 Subject: [PATCH 09/39] Fixes for investigations and spiribirds --- .../ConvenientSpiribird.ts | 2 +- mod/Investigations/Investigation.ts | 22 +++++++++++-------- mod/Investigations/QuestGenerator.ts | 11 +++++----- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/mod/ConvenientSpiribirds/ConvenientSpiribird.ts b/mod/ConvenientSpiribirds/ConvenientSpiribird.ts index 7264a88..63ca2a5 100644 --- a/mod/ConvenientSpiribirds/ConvenientSpiribird.ts +++ b/mod/ConvenientSpiribirds/ConvenientSpiribird.ts @@ -35,7 +35,7 @@ sdk.hook( let player = sdk.to_managed_object(self); let count = sdk.to_int64(cnt); - next_stamina_max = count * 30.0; + next_stamina_max = count * 30.0001; next_player = player; }, diff --git a/mod/Investigations/Investigation.ts b/mod/Investigations/Investigation.ts index 8e9d2f9..bbd66c5 100644 --- a/mod/Investigations/Investigation.ts +++ b/mod/Investigations/Investigation.ts @@ -10,7 +10,7 @@ import QCF = snow.gui.fsm.questcounter.GuiQuestCounterFsmManager; export interface InvestigationDef { map: number; target_monster: number; - extra_monster: [number, number]; + extra_monsters: [number, number]; pinned: boolean; } export interface Investigation extends InvestigationDef { @@ -37,9 +37,10 @@ function get_investigations(): Investigation[] { current_investigation_data.investigations = json.load_file(`Investigations/${current_name}.json`) ?? []; - for (let i of current_investigation_data.investigations) { - i.quest_data = generate_quest_data(i); + for (let inv of current_investigation_data.investigations) { + inv.quest_data = (generate_quest_data(inv) as REManagedObject).add_ref() } + current_investigation_data.current_player = current_name return current_investigation_data.investigations; } @@ -50,7 +51,7 @@ function save_investigations() { } json.dump_file( `Investigations/${current_name}.json`, - current_investigation_data + current_investigation_data.investigations ); } @@ -87,7 +88,7 @@ sdk.hook( } if (next_returned_text != undefined) { - return sdk.PreHookresult.SKIP_ORIGINAL + return sdk.PreHookResult.SKIP_ORIGINAL } }, @@ -108,13 +109,14 @@ sdk.hook(snow.QuestManager.M.questEnemyDie, ([_, self, mon]) => { let monster = sdk.to_managed_object(mon); let monster_id = monster.get_EnemyType(); - let inv = create_investigation(get_player_name(), monster_id) as Investigation if (!inv) { - return + log.info(`failed to create investigation for ${monster_id}`) + return; } - inv.quest_data = generate_quest_data(inv) + snow.gui.ChatManager.M.Instance?.reqAddChatBossIconInfo(monster_id, "New investigation", false, false) + inv.quest_data = (generate_quest_data(inv) as REManagedObject).add_ref() get_investigations().push(inv) save_investigations() }); @@ -132,12 +134,14 @@ sdk.hook(snow.QuestManager.M.makeQuestNoList, undefined, (retval) => { questCounter.getQuestCounterSelectedTopMenu() == QCF.QuestCounterTopMenuType.Normal_Hall_Master && questCounter.getQuestCounterSelectedRankMenu() == - QCF.QuestCounterRankMenuType.Master && + QCF.QuestCounterRankMenuType.None && questCounter.getQuestCounterSelectedLevelMenu() == QCF.QuestCounterLevelMenuType.Gathering ) { let list = sdk.to_managed_object(retval) let i = 0; + log.info("adding to list") + log.info(`${json.dump_string(get_investigations())}`) for (let inv of get_investigations()) { let new_quest_no = 942000 + i++; investigation_id_map[new_quest_no] = inv diff --git a/mod/Investigations/QuestGenerator.ts b/mod/Investigations/QuestGenerator.ts index 90a206f..d9394f3 100644 --- a/mod/Investigations/QuestGenerator.ts +++ b/mod/Investigations/QuestGenerator.ts @@ -254,8 +254,9 @@ function set_map(quest_data: snow.quest.QuestData, map_id: number) { } export function create_investigation(player_name: string, monster_id: number) { - let monster_data = Data.Monsters[monster_id]; - if (!monster_data || monster_data.MapIds.length > 0) { + let monster_data = Data.Monsters[monster_id.toString()]; + if (!monster_data || monster_data.MapIds.length == 0) { + log.info(`not enough monster data for monster ${monster_id}`) return; } @@ -272,7 +273,7 @@ export function create_investigation(player_name: string, monster_id: number) { let investigation: InvestigationDef = { map, target_monster: monster_id, - extra_monster: [pickr(monsters_in_map), pickr(monsters_in_map)], + extra_monsters: [pickr(monsters_in_map), pickr(monsters_in_map)], pinned: false, }; return investigation; @@ -287,8 +288,8 @@ export function generate_quest_data( let quest_data = create_base_quest_data(); set_map(quest_data, investigation.map); set_quest_target(quest_data, investigation.target_monster); - set_extra(quest_data, investigation.extra_monster[0], 1); - set_extra(quest_data, investigation.extra_monster[1], 2); + set_extra(quest_data, investigation.extra_monsters[0], 1); + set_extra(quest_data, investigation.extra_monsters[1], 2); return quest_data; } From fc3941b287bab4e919d5caef8ee20c2a9925f49e Mon Sep 17 00:00:00 2001 From: Strackeror Date: Thu, 28 Jul 2022 18:05:03 +0200 Subject: [PATCH 10/39] Copy mod script --- copy-mod.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 copy-mod.py diff --git a/copy-mod.py b/copy-mod.py new file mode 100644 index 0000000..17e0975 --- /dev/null +++ b/copy-mod.py @@ -0,0 +1,14 @@ +import sys +import os +import shutil + +mhrise_path=r"C:\Program Files (x86)\Steam\steamapps\common\MonsterHunterRise" +mod = sys.argv[1] + +os.system("npx tstl -p " + mod) + +shutil.copytree( + os.path.join(mod, "dist"), + os.path.join(mhrise_path, "reframework", "autorun"), + dirs_exist_ok=True +) From 43d6a7f86fd88cca6208e6d10b8ff1b80279f7ad Mon Sep 17 00:00:00 2001 From: Strackeror Date: Fri, 29 Jul 2022 15:10:53 +0200 Subject: [PATCH 11/39] Remove direct collection indices --- .../ConvenientSpiribird.ts | 2 +- mod/Investigations/Investigation.ts | 2 +- mod/Investigations/QuestGenerator.ts | 44 +++++++++---------- mod/Investigations/Utilities.ts | 2 +- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/mod/ConvenientSpiribirds/ConvenientSpiribird.ts b/mod/ConvenientSpiribirds/ConvenientSpiribird.ts index 63ca2a5..d8468eb 100644 --- a/mod/ConvenientSpiribirds/ConvenientSpiribird.ts +++ b/mod/ConvenientSpiribirds/ConvenientSpiribird.ts @@ -19,7 +19,7 @@ if (!player) { let arr = param._StatusBuffAddValue; for (let i = 0; i < arr.get_Length(); ++i) { log.info(`${param._Id}[${i}]=${arr.get_Item(i)}`) - arr[i] = arr[i] * SPIRIBIRD_MULTIPLIER; + arr.Set(i, arr.Get(i) * SPIRIBIRD_MULTIPLIER) } return retval diff --git a/mod/Investigations/Investigation.ts b/mod/Investigations/Investigation.ts index bbd66c5..b9959e8 100644 --- a/mod/Investigations/Investigation.ts +++ b/mod/Investigations/Investigation.ts @@ -145,7 +145,7 @@ sdk.hook(snow.QuestManager.M.makeQuestNoList, undefined, (retval) => { for (let inv of get_investigations()) { let new_quest_no = 942000 + i++; investigation_id_map[new_quest_no] = inv - questManager._QuestDataDictionary[new_quest_no] = inv.quest_data + questManager._QuestDataDictionary.Add(new_quest_no, inv.quest_data) update_quest_no(inv.quest_data, new_quest_no) list.Add(new_quest_no) } diff --git a/mod/Investigations/QuestGenerator.ts b/mod/Investigations/QuestGenerator.ts index d9394f3..2a81f54 100644 --- a/mod/Investigations/QuestGenerator.ts +++ b/mod/Investigations/QuestGenerator.ts @@ -177,19 +177,19 @@ function can_capture(monster_data: MonsterData) { } function set_enemy_data(quest_enemy_data: snow.quest.NormalQuestDataForEnemy.Param, enemy_data: EnemyData, index: number) { - quest_enemy_data._RouteNo[index] = enemy_data["_RouteNo"] - quest_enemy_data._PartsTbl[index] = enemy_data["_PartsTbl"] - quest_enemy_data._InitSetName[index] = enemy_data["_InitSetName"] - quest_enemy_data._SubType[index] = enemy_data["_SubType"] - quest_enemy_data._VitalTbl[index] = enemy_data["_VitalTbl"] - quest_enemy_data._AttackTbl[index] = enemy_data["_AttackTbl"] - quest_enemy_data._OtherTbl[index] = enemy_data["_OtherTbl"] - quest_enemy_data._StaminaTbl[index] = enemy_data["_StaminaTbl"] - quest_enemy_data._Scale[index] = enemy_data["_Scale"] - quest_enemy_data._ScaleTbl[index] = enemy_data["_ScaleTbl"] - quest_enemy_data._Difficulty[index] = enemy_data["_Difficulty"] - quest_enemy_data._BossMulti[index] = enemy_data["_BossMulti"] - quest_enemy_data._IndividualType[index] = enemy_data["_IndividualType"] + quest_enemy_data._RouteNo.Set(index, enemy_data["_RouteNo"]) + quest_enemy_data._PartsTbl.Set(index, enemy_data["_PartsTbl"]) + quest_enemy_data._InitSetName.Set(index, enemy_data["_InitSetName"]) + quest_enemy_data._SubType.Set(index, enemy_data["_SubType"]) + quest_enemy_data._VitalTbl.Set(index, enemy_data["_VitalTbl"]) + quest_enemy_data._AttackTbl.Set(index, enemy_data["_AttackTbl"]) + quest_enemy_data._OtherTbl.Set(index, enemy_data["_OtherTbl"]) + quest_enemy_data._StaminaTbl.Set(index, enemy_data["_StaminaTbl"]) + quest_enemy_data._Scale.Set(index, enemy_data["_Scale"]) + quest_enemy_data._ScaleTbl.Set(index, enemy_data["_ScaleTbl"]) + quest_enemy_data._Difficulty.Set(index, enemy_data["_Difficulty"]) + quest_enemy_data._BossMulti.Set(index, enemy_data["_BossMulti"]) + quest_enemy_data._IndividualType.Set(index, enemy_data["_IndividualType"]) } function set_quest_target( @@ -207,18 +207,18 @@ function set_quest_target( let normal_quest_data = quest_data.get_RawNormal(); normal_quest_data._QuestType = snow.quest.QuestType.HUNTING; - normal_quest_data._TargetType[0] = snow.quest.QuestTargetType.Hunting; + normal_quest_data._TargetType.Set(0, snow.quest.QuestTargetType.Hunting); if (!can_capture(monster_data)) { (normal_quest_data._QuestType = snow.quest.QuestType.KILL), - (normal_quest_data._TargetType[0] = snow.quest.QuestTargetType.Kill); + (normal_quest_data._TargetType.Set(0, snow.quest.QuestTargetType.Kill)); } - normal_quest_data._TgtEmType[0] = monster_data.Id; - normal_quest_data._TgtNum[0] = 1; + normal_quest_data._TgtEmType.Set(0, monster_data.Id); + normal_quest_data._TgtNum.Set(0, 1); - normal_quest_data._BossEmType[0] = monster_data.Id; - normal_quest_data._BossSetCondition[0] = 1; - normal_quest_data._Icon[0] = monster_data.Icon; + normal_quest_data._BossEmType.Set(0, monster_data.Id); + normal_quest_data._BossSetCondition.Set(0, 1); + normal_quest_data._Icon.Set(0, monster_data.Icon); normal_quest_data._QuestLv = monster_data.QuestLevel; let enemy_quest_data = quest_data.get_RawEnemy(); @@ -239,8 +239,8 @@ function set_extra( let normal = quest_data.get_RawNormal(); normal._InitExtraEmNum += 1; - normal._BossEmType[index] = monster_id; - normal._BossSetCondition[index] = 1; + normal._BossEmType.Set(index, monster_id); + normal._BossSetCondition.Set(index, 1); let enemy_quest_data = quest_data.get_RawEnemy(); let enemy_data = monster_data.EnemyDataList["0"][0] diff --git a/mod/Investigations/Utilities.ts b/mod/Investigations/Utilities.ts index 1729af8..64fd432 100644 --- a/mod/Investigations/Utilities.ts +++ b/mod/Investigations/Utilities.ts @@ -12,7 +12,7 @@ export function create_array( export function create_array(type: string, table: any[]): System.Array.Generic { let array = sdk.create_managed_array(type, table.length); for (let i = 0; i < table.length; ++i) { - array[i] = table[i]; + array.Set(i, table[i]) } return array; } From 1cd21fa6e2b3593aab03d1ebbcbf2d3a12d8e7f6 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Fri, 29 Jul 2022 15:13:07 +0200 Subject: [PATCH 12/39] Improve script --- copy-mod.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/copy-mod.py b/copy-mod.py index 17e0975..0940feb 100644 --- a/copy-mod.py +++ b/copy-mod.py @@ -3,12 +3,11 @@ import shutil mhrise_path=r"C:\Program Files (x86)\Steam\steamapps\common\MonsterHunterRise" -mod = sys.argv[1] +for mod in sys.argv[1:]: + os.system("npx tstl -p " + mod) -os.system("npx tstl -p " + mod) - -shutil.copytree( - os.path.join(mod, "dist"), - os.path.join(mhrise_path, "reframework", "autorun"), - dirs_exist_ok=True -) + shutil.copytree( + os.path.join(mod, "dist"), + os.path.join(mhrise_path, "reframework", "autorun"), + dirs_exist_ok=True + ) From 83c7200b1bcc440e04e8b1839e72094bd5c9b7f7 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Fri, 29 Jul 2022 21:20:31 +0200 Subject: [PATCH 13/39] Prevent exception when replacing quest in dictionary --- mod/Investigations/Investigation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/Investigations/Investigation.ts b/mod/Investigations/Investigation.ts index b9959e8..df2e318 100644 --- a/mod/Investigations/Investigation.ts +++ b/mod/Investigations/Investigation.ts @@ -145,7 +145,7 @@ sdk.hook(snow.QuestManager.M.makeQuestNoList, undefined, (retval) => { for (let inv of get_investigations()) { let new_quest_no = 942000 + i++; investigation_id_map[new_quest_no] = inv - questManager._QuestDataDictionary.Add(new_quest_no, inv.quest_data) + questManager._QuestDataDictionary.set_Item(new_quest_no, inv.quest_data) update_quest_no(inv.quest_data, new_quest_no) list.Add(new_quest_no) } From c5319bcd98121cf5101f25734e099e3f51499814 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Sat, 30 Jul 2022 21:02:25 +0200 Subject: [PATCH 14/39] Use Instance directly in managers --- mod/Investigations/Investigation.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/mod/Investigations/Investigation.ts b/mod/Investigations/Investigation.ts index df2e318..69c0bbc 100644 --- a/mod/Investigations/Investigation.ts +++ b/mod/Investigations/Investigation.ts @@ -27,7 +27,7 @@ let investigation_id_map: { } = {}; function get_investigations(): Investigation[] { - const current_name = snow.SnowSaveService.M.Instance?.getCurrentHunterName(); + const current_name = snow.SnowSaveService.Instance?.getCurrentHunterName(); if (!current_name) { return []; } @@ -45,7 +45,7 @@ function get_investigations(): Investigation[] { } function save_investigations() { - const current_name = snow.SnowSaveService.M.Instance?.getCurrentHunterName(); + const current_name = snow.SnowSaveService.Instance?.getCurrentHunterName(); if (!current_name) { return; } @@ -57,7 +57,7 @@ function save_investigations() { function get_player_name(): string { return ( - snow.SnowSaveService.M.Instance?.getCurrentHunterName() ?? "__Unknown__" + snow.SnowSaveService.Instance?.getCurrentHunterName() ?? "__Unknown__" ); } @@ -115,16 +115,15 @@ sdk.hook(snow.QuestManager.M.questEnemyDie, ([_, self, mon]) => { return; } - snow.gui.ChatManager.M.Instance?.reqAddChatBossIconInfo(monster_id, "New investigation", false, false) + snow.gui.ChatManager.Instance?.reqAddChatBossIconInfo(monster_id, "New investigation", false, false) inv.quest_data = (generate_quest_data(inv) as REManagedObject).add_ref() get_investigations().push(inv) save_investigations() }); sdk.hook(snow.QuestManager.M.makeQuestNoList, undefined, (retval) => { - let questCounter = - snow.gui.fsm.questcounter.GuiQuestCounterFsmManager.M.Instance; - let questManager = snow.QuestManager.M.Instance; + let questCounter = QCF.Instance; + let questManager = snow.QuestManager.Instance; if (!questCounter || !questManager) { return retval From 6b3b6d3cab051030decae1ea381444111913c8fa Mon Sep 17 00:00:00 2001 From: Strackeror Date: Tue, 2 Aug 2022 23:51:33 +0200 Subject: [PATCH 15/39] Update mods with class hierarchy --- .gitignore | 1 + IL2CPP/type-filters.json | 7 +++++-- mod/ConvenientSpiribirds/ConvenientSpiribird.ts | 2 +- mod/Investigations/Investigation.ts | 10 +++++----- mod/Investigations/tsconfig.json | 1 - 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 9aaafa8..2eadd02 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ typemap.d.ts **/dist/*/* node_modules/ output/ +/dist diff --git a/IL2CPP/type-filters.json b/IL2CPP/type-filters.json index 3df631e..0d89a3b 100644 --- a/IL2CPP/type-filters.json +++ b/IL2CPP/type-filters.json @@ -1,8 +1,11 @@ { "namespace_tree_filter": [ - "snow.Snow" + "snow.Snow", + "snow.gui.StmGui", + "snow.gui.Snow" ], "type_map_filter": [ - "snow.SnowSingleton" + "snow.SnowSingleton", + "snow.quest\\." ] } diff --git a/mod/ConvenientSpiribirds/ConvenientSpiribird.ts b/mod/ConvenientSpiribirds/ConvenientSpiribird.ts index d8468eb..6a167a4 100644 --- a/mod/ConvenientSpiribirds/ConvenientSpiribird.ts +++ b/mod/ConvenientSpiribirds/ConvenientSpiribird.ts @@ -30,7 +30,7 @@ if (!player) { let next_stamina_max = 0.0 let next_player: snow.player.PlayerQuestBase; sdk.hook( - snow.player.PlayerQuestBase.M.calcLvBuffStamina, + snow.player.PlayerQuestBase.calcLvBuffStamina, ([_1, self, cnt]) => { let player = sdk.to_managed_object(self); let count = sdk.to_int64(cnt); diff --git a/mod/Investigations/Investigation.ts b/mod/Investigations/Investigation.ts index 69c0bbc..e8d106e 100644 --- a/mod/Investigations/Investigation.ts +++ b/mod/Investigations/Investigation.ts @@ -38,7 +38,7 @@ function get_investigations(): Investigation[] { current_investigation_data.investigations = json.load_file(`Investigations/${current_name}.json`) ?? []; for (let inv of current_investigation_data.investigations) { - inv.quest_data = (generate_quest_data(inv) as REManagedObject).add_ref() + inv.quest_data = generate_quest_data(inv).add_ref() } current_investigation_data.current_player = current_name return current_investigation_data.investigations; @@ -63,7 +63,7 @@ function get_player_name(): string { let next_returned_text: string | undefined = undefined sdk.hook( - snow.quest.QuestData.M.getQuestTextCore, + snow.quest.QuestData.getQuestTextCore, (args) => { let self = sdk.to_managed_object(args[1]) let quest_text: snow.quest.QuestText = sdk.to_int64(args[2]) @@ -100,7 +100,7 @@ sdk.hook( } ) -sdk.hook(snow.QuestManager.M.questEnemyDie, ([_, self, mon]) => { +sdk.hook(snow.QuestManager.questEnemyDie, ([_, self, mon]) => { let quest_mgr = sdk.to_managed_object(self); if (quest_mgr.getQuestRank_Lv() != snow.QuestManager.QuestRank.Master) { @@ -116,12 +116,12 @@ sdk.hook(snow.QuestManager.M.questEnemyDie, ([_, self, mon]) => { } snow.gui.ChatManager.Instance?.reqAddChatBossIconInfo(monster_id, "New investigation", false, false) - inv.quest_data = (generate_quest_data(inv) as REManagedObject).add_ref() + inv.quest_data = generate_quest_data(inv).add_ref() get_investigations().push(inv) save_investigations() }); -sdk.hook(snow.QuestManager.M.makeQuestNoList, undefined, (retval) => { +sdk.hook(snow.QuestManager.makeQuestNoList, undefined, (retval) => { let questCounter = QCF.Instance; let questManager = snow.QuestManager.Instance; diff --git a/mod/Investigations/tsconfig.json b/mod/Investigations/tsconfig.json index 3c68caf..aeb2040 100644 --- a/mod/Investigations/tsconfig.json +++ b/mod/Investigations/tsconfig.json @@ -15,7 +15,6 @@ "./*" ], }, - "strict": true, }, "tstl": { "luaLibImport": "inline", From 9a40ac32801b7cb67f997e08b44778916801196b Mon Sep 17 00:00:00 2001 From: Strackeror Date: Wed, 3 Aug 2022 22:25:34 +0200 Subject: [PATCH 16/39] New mod: Jump to quest monster journal page --- mod/MonsterJournalPage/MonsterJournalPage.ts | 84 +++++++++++++++++++ .../dist/MonsterJournalPage.lua | 1 + mod/MonsterJournalPage/tsconfig.json | 30 +++++++ 3 files changed, 115 insertions(+) create mode 100644 mod/MonsterJournalPage/MonsterJournalPage.ts create mode 100644 mod/MonsterJournalPage/dist/MonsterJournalPage.lua create mode 100644 mod/MonsterJournalPage/tsconfig.json diff --git a/mod/MonsterJournalPage/MonsterJournalPage.ts b/mod/MonsterJournalPage/MonsterJournalPage.ts new file mode 100644 index 0000000..1124587 --- /dev/null +++ b/mod/MonsterJournalPage/MonsterJournalPage.ts @@ -0,0 +1,84 @@ +import { snow } from "MonsterJournalPage/IL2CPP"; + +function get_current_target_monsters(): snow.enemy.EnemyDef.EmTypes[] { + let current_quest = snow.QuestManager.Instance.getActiveQuestData(); + if (!current_quest) { + return []; + } + + let data = current_quest.get_RawNormal(); + if (!data) { + return []; + } + + if (data._TargetType.Get(0) == snow.quest.QuestTargetType.AllMainEnemy) { + let ret = []; + for (let i = 0; i < data._BossEmType.get_Count(); ++i) { + let em = data._BossEmType.Get(i); + if (em != 0) { + ret.push(data._BossEmType.Get(i)); + } + } + return ret; + } + + let ret = []; + for (let i = 0; i < data._TgtEmType.get_Count(); ++i) { + let em = data._TgtEmType.Get(i); + if (em != 0) { + ret.push(data._TgtEmType.Get(i)); + } + } + return ret; +} + +let current_idx = 0; + +sdk.hook(snow.gui.GuiMonsterList.start, (args) => { + current_idx = 0; +}); + +sdk.hook(snow.gui.GuiMonsterList.update, (args) => { + let mon_list = sdk.to_managed_object(args[1]); + + if ( + snow.gui.StmGuiInput.andTrg( + snow.StmInputManager.UI_INPUT.STATIC_MENU_ACT_TYPE_CL, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + false, + false + ) + ) { + let mons = get_current_target_monsters(); + if (mons.length > 0) { + let mon_to_show = mons[current_idx % mons.length]; + current_idx += 1; + log.info(`first monster: ${mon_to_show}`); + for (let i = 0; i < mon_list._MonsterList.mSize; ++i) { + if (mon_list._MonsterList.get_Item(i)._Data._EmType == mon_to_show) { + let selected_index = + mon_list._MonsterListScrollCtrl.get_selectedIndex(); + selected_index._HasValue = true; + selected_index._Value = i; + mon_list._MonsterListScrollCtrl.set_selectedIndex(selected_index); + + snow.gui.SnowGuiCommonUtility.reqSe(0xf4b6879b); // sound effect woo + + mon_list.updateTopTab(); + mon_list._MonsterListScrollCtrl.selectedIndexToCursorSelect(); + mon_list.setupMainPage(false, true); + mon_list.updateMainPage(true); + return; + } + } + } + } +}); diff --git a/mod/MonsterJournalPage/dist/MonsterJournalPage.lua b/mod/MonsterJournalPage/dist/MonsterJournalPage.lua new file mode 100644 index 0000000..02b4fca --- /dev/null +++ b/mod/MonsterJournalPage/dist/MonsterJournalPage.lua @@ -0,0 +1 @@ +require("MonsterJournalPage.MonsterJournalPage") diff --git a/mod/MonsterJournalPage/tsconfig.json b/mod/MonsterJournalPage/tsconfig.json new file mode 100644 index 0000000..178d693 --- /dev/null +++ b/mod/MonsterJournalPage/tsconfig.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://raw.githubusercontent.com/TypeScriptToLua/TypeScriptToLua/master/tsconfig-schema.json", + "compilerOptions": { + "lib": [ + "ESNext" + ], + "types": [ + "lua-types/5.4" + ], + "outDir": "./dist/MonsterJournalPage", + "baseUrl": ".", + "paths": { + "MonsterJournalPage/*": [ + "./*", + "../../IL2CPP/*" + ] + }, + "noImplicitAny": true + }, + "tstl": { + "luaLibImport": "inline", + "luaTarget": "5.3", + "measurePerformance": true, + "noImplicitGlobalVariables": true, + }, + "include": [ + "./*", + "../../IL2CPP/*" + ] +} \ No newline at end of file From 53e3958ff0174d34a2626ba6e54492fd24a1a515 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Thu, 4 Aug 2022 23:50:05 +0200 Subject: [PATCH 17/39] Add plugin for correct mod path output --- .gitignore | 3 +- IL2CPP/type-filters.json | 3 +- copy-mod.py | 3 +- mod-exporter-plugin/mod-export-path.ts | 67 ++++ ...ntSpiribird.ts => ConvenientSpiribirds.ts} | 2 +- .../dist/ConvenientSpiribirds.lua | 1 - mod/ConvenientSpiribirds/tsconfig.json | 13 +- .../{Investigation.ts => Investigations.ts} | 4 +- mod/Investigations/QuestGenerator.ts | 8 +- mod/Investigations/Utilities.ts | 2 +- mod/Investigations/dist/Investigations.lua | 1 - mod/Investigations/tsconfig.json | 17 +- mod/MonsterJournalPage/MonsterJournalPage.ts | 2 +- .../dist/MonsterJournalPage.lua | 1 - mod/MonsterJournalPage/tsconfig.json | 11 +- package-lock.json | 330 +++++++++++++++++- package-mods.py | 11 +- package.json | 1 + 18 files changed, 429 insertions(+), 51 deletions(-) create mode 100644 mod-exporter-plugin/mod-export-path.ts rename mod/ConvenientSpiribirds/{ConvenientSpiribird.ts => ConvenientSpiribirds.ts} (96%) delete mode 100644 mod/ConvenientSpiribirds/dist/ConvenientSpiribirds.lua rename mod/Investigations/{Investigation.ts => Investigations.ts} (98%) delete mode 100644 mod/Investigations/dist/Investigations.lua delete mode 100644 mod/MonsterJournalPage/dist/MonsterJournalPage.lua diff --git a/.gitignore b/.gitignore index 2eadd02..0977fdc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ il2cpp_dump.json il2cpp.d.ts typemap.d.ts -**/dist/*/* +dist/ node_modules/ output/ -/dist diff --git a/IL2CPP/type-filters.json b/IL2CPP/type-filters.json index 0d89a3b..b59c90e 100644 --- a/IL2CPP/type-filters.json +++ b/IL2CPP/type-filters.json @@ -2,7 +2,8 @@ "namespace_tree_filter": [ "snow.Snow", "snow.gui.StmGui", - "snow.gui.Snow" + "snow.gui.Snow", + "snow.envCreature.Ec008" ], "type_map_filter": [ "snow.SnowSingleton", diff --git a/copy-mod.py b/copy-mod.py index 0940feb..7499b8e 100644 --- a/copy-mod.py +++ b/copy-mod.py @@ -1,8 +1,9 @@ import sys import os import shutil +import json -mhrise_path=r"C:\Program Files (x86)\Steam\steamapps\common\MonsterHunterRise" +mhrise_path = json.load(open("dist/RisePath.json"))["RisePath"] for mod in sys.argv[1:]: os.system("npx tstl -p " + mod) diff --git a/mod-exporter-plugin/mod-export-path.ts b/mod-exporter-plugin/mod-export-path.ts new file mode 100644 index 0000000..7c1955b --- /dev/null +++ b/mod-exporter-plugin/mod-export-path.ts @@ -0,0 +1,67 @@ +import * as tstl from "typescript-to-lua" +import * as path from "path" +import * as fs from "fs"; + + + +function findRequiredPaths(code: string): string[] { + // Find all require("") paths in a lua code string + const paths: string[] = []; + const pattern = /(^|\s|;|=|\()require\("(.+?)"\)/g; + // eslint-disable-next-line @typescript-eslint/ban-types + let match: RegExpExecArray | null; + while ((match = pattern.exec(code))) { + paths.push(match[2]); + } + + return paths; +} + +function addExtraPathInCode(file: tstl.EmitFile, originalRequire: string, containerFolder: string): void { + + // Escape special characters to prevent the regex from breaking... + const escapedRequire = originalRequire.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&"); + + file.code = file.code.replace( + new RegExp(`(^|\\s|;|=|\\()require\\("(${escapedRequire})"\\)`), + `$1require("${containerFolder}.$2")` + ); +} + +const plugin: tstl.Plugin = { + beforeEmit(program, options, emitHost, result) { + let outdir = program.getCompilerOptions().outDir; + if (!outdir) { + return; + } + + let pkgPath = path.resolve( + program.getCurrentDirectory(), + program.getCompilerOptions().project ?? "." + ); + + if (pkgPath.endsWith(".json")) { + pkgPath = path.dirname(pkgPath) + } + let project_name = path.basename(pkgPath) + + console.log(project_name) + for (let file of result) { + for (let r of findRequiredPaths(file.code)) { + addExtraPathInCode(file, r, project_name) + } + let relpath = path.relative(outdir, file.outputPath) + file.outputPath = path.join(outdir, project_name, relpath) + console.error(file.outputPath) + } + + fs.mkdirSync(outdir, {recursive: true}) + fs.writeFileSync( + path.join(outdir, project_name + ".lua"), + `require("${project_name}.${project_name}")` + ); + }, + +}; + +export default plugin; \ No newline at end of file diff --git a/mod/ConvenientSpiribirds/ConvenientSpiribird.ts b/mod/ConvenientSpiribirds/ConvenientSpiribirds.ts similarity index 96% rename from mod/ConvenientSpiribirds/ConvenientSpiribird.ts rename to mod/ConvenientSpiribirds/ConvenientSpiribirds.ts index 6a167a4..d3cc2fd 100644 --- a/mod/ConvenientSpiribirds/ConvenientSpiribird.ts +++ b/mod/ConvenientSpiribirds/ConvenientSpiribirds.ts @@ -1,4 +1,4 @@ -import {snow} from "ConvenientSpiribirds/IL2CPP" +import {snow} from "IL2CPP/IL2CPP" import LvBuffCageId = snow.data.ContentsIdSystem.LvBuffCageId; diff --git a/mod/ConvenientSpiribirds/dist/ConvenientSpiribirds.lua b/mod/ConvenientSpiribirds/dist/ConvenientSpiribirds.lua deleted file mode 100644 index 3eed9ef..0000000 --- a/mod/ConvenientSpiribirds/dist/ConvenientSpiribirds.lua +++ /dev/null @@ -1 +0,0 @@ -require("ConvenientSpiribirds.ConvenientSpiribird") diff --git a/mod/ConvenientSpiribirds/tsconfig.json b/mod/ConvenientSpiribirds/tsconfig.json index ddeefd8..dd5300a 100644 --- a/mod/ConvenientSpiribirds/tsconfig.json +++ b/mod/ConvenientSpiribirds/tsconfig.json @@ -7,19 +7,24 @@ "types": [ "lua-types/5.4" ], - "outDir": "./dist/ConvenientSpiribirds", "baseUrl": ".", "paths": { - "ConvenientSpiribirds/*": [ - "./*", + "IL2CPP/*": [ "../../IL2CPP/*" ] - } + }, + "outDir": "./dist" }, "tstl": { "luaLibImport": "inline", "luaTarget": "5.3", "measurePerformance": true, + "noImplicitGlobalVariables": true, + "luaPlugins": [ + { + "name": "../../mod-exporter-plugin/mod-export-path.ts" + } + ] }, "include": [ "./*", diff --git a/mod/Investigations/Investigation.ts b/mod/Investigations/Investigations.ts similarity index 98% rename from mod/Investigations/Investigation.ts rename to mod/Investigations/Investigations.ts index e8d106e..aa8d69a 100644 --- a/mod/Investigations/Investigation.ts +++ b/mod/Investigations/Investigations.ts @@ -1,10 +1,10 @@ -import { snow } from "Investigations/IL2CPP"; +import { snow } from "IL2CPP/IL2CPP"; import { create_investigation, generate_quest_data, get_monster_name, update_quest_no, -} from "Investigations/QuestGenerator"; +} from "./QuestGenerator"; import QCF = snow.gui.fsm.questcounter.GuiQuestCounterFsmManager; export interface InvestigationDef { diff --git a/mod/Investigations/QuestGenerator.ts b/mod/Investigations/QuestGenerator.ts index 2a81f54..a2c5a65 100644 --- a/mod/Investigations/QuestGenerator.ts +++ b/mod/Investigations/QuestGenerator.ts @@ -1,7 +1,7 @@ -import { snow } from "Investigations/IL2CPP"; -import { create_array } from "Investigations/Utilities"; -import { Data, EnemyData, MonsterData } from "Investigations/InvestigationData"; -import { Investigation, InvestigationDef } from "Investigations/Investigation"; +import { snow } from "IL2CPP/IL2CPP"; +import { create_array } from "./Utilities"; +import { Data, EnemyData, MonsterData } from "./InvestigationData"; +import { Investigation, InvestigationDef } from "./Investigations"; import QuestOrderType = snow.quest.QuestOrderType; diff --git a/mod/Investigations/Utilities.ts b/mod/Investigations/Utilities.ts index 64fd432..a8499e5 100644 --- a/mod/Investigations/Utilities.ts +++ b/mod/Investigations/Utilities.ts @@ -1,4 +1,4 @@ -import { System } from "Investigations/IL2CPP"; +import { System } from "IL2CPP/IL2CPP"; export function create_array( type: T, diff --git a/mod/Investigations/dist/Investigations.lua b/mod/Investigations/dist/Investigations.lua deleted file mode 100644 index 7b9dc84..0000000 --- a/mod/Investigations/dist/Investigations.lua +++ /dev/null @@ -1 +0,0 @@ -require("Investigations.Investigation") diff --git a/mod/Investigations/tsconfig.json b/mod/Investigations/tsconfig.json index aeb2040..dd5300a 100644 --- a/mod/Investigations/tsconfig.json +++ b/mod/Investigations/tsconfig.json @@ -7,22 +7,27 @@ "types": [ "lua-types/5.4" ], - "outDir": "./dist/Investigations", "baseUrl": ".", "paths": { - "Investigations/*": [ - "../../IL2CPP/*", - "./*" - ], + "IL2CPP/*": [ + "../../IL2CPP/*" + ] }, + "outDir": "./dist" }, "tstl": { "luaLibImport": "inline", "luaTarget": "5.3", "measurePerformance": true, + "noImplicitGlobalVariables": true, + "luaPlugins": [ + { + "name": "../../mod-exporter-plugin/mod-export-path.ts" + } + ] }, "include": [ - "./**/*", + "./*", "../../IL2CPP/*" ] } \ No newline at end of file diff --git a/mod/MonsterJournalPage/MonsterJournalPage.ts b/mod/MonsterJournalPage/MonsterJournalPage.ts index 1124587..5144bb7 100644 --- a/mod/MonsterJournalPage/MonsterJournalPage.ts +++ b/mod/MonsterJournalPage/MonsterJournalPage.ts @@ -1,4 +1,4 @@ -import { snow } from "MonsterJournalPage/IL2CPP"; +import { snow } from "IL2CPP/IL2CPP"; function get_current_target_monsters(): snow.enemy.EnemyDef.EmTypes[] { let current_quest = snow.QuestManager.Instance.getActiveQuestData(); diff --git a/mod/MonsterJournalPage/dist/MonsterJournalPage.lua b/mod/MonsterJournalPage/dist/MonsterJournalPage.lua deleted file mode 100644 index 02b4fca..0000000 --- a/mod/MonsterJournalPage/dist/MonsterJournalPage.lua +++ /dev/null @@ -1 +0,0 @@ -require("MonsterJournalPage.MonsterJournalPage") diff --git a/mod/MonsterJournalPage/tsconfig.json b/mod/MonsterJournalPage/tsconfig.json index 178d693..dd5300a 100644 --- a/mod/MonsterJournalPage/tsconfig.json +++ b/mod/MonsterJournalPage/tsconfig.json @@ -7,21 +7,24 @@ "types": [ "lua-types/5.4" ], - "outDir": "./dist/MonsterJournalPage", "baseUrl": ".", "paths": { - "MonsterJournalPage/*": [ - "./*", + "IL2CPP/*": [ "../../IL2CPP/*" ] }, - "noImplicitAny": true + "outDir": "./dist" }, "tstl": { "luaLibImport": "inline", "luaTarget": "5.3", "measurePerformance": true, "noImplicitGlobalVariables": true, + "luaPlugins": [ + { + "name": "../../mod-exporter-plugin/mod-export-path.ts" + } + ] }, "include": [ "./*", diff --git a/package-lock.json b/package-lock.json index 1a85904..903abb8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,9 +6,120 @@ "": { "devDependencies": { "lua-types": "^2.11.0", + "ts-node": "^10.9.1", "typescript-to-lua": "^1.7.1" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.6.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.3.tgz", + "integrity": "sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg==", + "dev": true, + "peer": true + }, + "node_modules/acorn": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/enhanced-resolve": { "version": "5.10.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", @@ -47,9 +158,9 @@ } }, "node_modules/is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", "dev": true, "dependencies": { "has": "^1.0.3" @@ -67,6 +178,12 @@ "typescript-to-lua": "^1.0.0" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -120,6 +237,49 @@ "node": ">=6" } }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, "node_modules/typescript": { "version": "4.7.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", @@ -135,9 +295,9 @@ } }, "node_modules/typescript-to-lua": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.7.1.tgz", - "integrity": "sha512-iDjCnel38p3Cxv+Las8rBzd6BaRIE49DQSyFOgupg4gSw36+8H1xtwde3lRdGMPZx19/zVwXEO8UspiACYJc+A==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.7.2.tgz", + "integrity": "sha512-ybQwsFXdBqT9iWXavbJmLvB+P8DeXWXWzkqrsTaZ95QqIbp9DtVfVAYdUvchaO9IVKm4yk0GkSgPJhpFosxv8w==", "dev": true, "dependencies": { "enhanced-resolve": "^5.8.2", @@ -153,9 +313,116 @@ "peerDependencies": { "typescript": "~4.7.3" } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } } }, "dependencies": { + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, + "@types/node": { + "version": "18.6.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.3.tgz", + "integrity": "sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg==", + "dev": true, + "peer": true + }, + "acorn": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "dev": true + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, "enhanced-resolve": { "version": "5.10.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", @@ -188,9 +455,9 @@ } }, "is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", "dev": true, "requires": { "has": "^1.0.3" @@ -203,6 +470,12 @@ "dev": true, "requires": {} }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -238,6 +511,27 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, "typescript": { "version": "4.7.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", @@ -246,15 +540,27 @@ "peer": true }, "typescript-to-lua": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.7.1.tgz", - "integrity": "sha512-iDjCnel38p3Cxv+Las8rBzd6BaRIE49DQSyFOgupg4gSw36+8H1xtwde3lRdGMPZx19/zVwXEO8UspiACYJc+A==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.7.2.tgz", + "integrity": "sha512-ybQwsFXdBqT9iWXavbJmLvB+P8DeXWXWzkqrsTaZ95QqIbp9DtVfVAYdUvchaO9IVKm4yk0GkSgPJhpFosxv8w==", "dev": true, "requires": { "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", "source-map": "^0.7.3" } + }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true } } } diff --git a/package-mods.py b/package-mods.py index 6ef3392..34dee10 100644 --- a/package-mods.py +++ b/package-mods.py @@ -4,6 +4,7 @@ os.chdir(os.path.dirname(__file__)) + def zipfolder(foldername: str, zip_path: str): with ZipFile(zip_path, 'w') as zipfile: for root, dirs, files in os.walk(foldername): @@ -15,12 +16,4 @@ def zipfolder(foldername: str, zip_path: str): os.path.join('reframework', "autorun", os.path.relpath( filepath, foldername - ))) - - -os.makedirs("output", exist_ok=True) -mod_dirs = next(os.walk("mod"))[1] -for m in mod_dirs: - name = os.path.basename(m) - shutil.copy(os.path.join("IL2CPP", "IL2CPP.lua"), os.path.join("mod", name, "dist", name)) - zipfolder(os.path.join("mod", name, "dist"), os.path.join("output", f"{name}.zip")) + ))) diff --git a/package.json b/package.json index 540c3d4..cb50a6f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "devDependencies": { "lua-types": "^2.11.0", + "ts-node": "^10.9.1", "typescript-to-lua": "^1.7.1" } } From 965115696950a462f493cd8de459073c0c21e235 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Fri, 5 Aug 2022 12:39:38 +0200 Subject: [PATCH 18/39] Auto wirebuff pickup --- IL2CPP/type-filters.json | 2 +- .../ConvenientSpiribirds.ts | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/IL2CPP/type-filters.json b/IL2CPP/type-filters.json index b59c90e..4b2d51f 100644 --- a/IL2CPP/type-filters.json +++ b/IL2CPP/type-filters.json @@ -3,7 +3,7 @@ "snow.Snow", "snow.gui.StmGui", "snow.gui.Snow", - "snow.envCreature.Ec008" + "snow.envCreature" ], "type_map_filter": [ "snow.SnowSingleton", diff --git a/mod/ConvenientSpiribirds/ConvenientSpiribirds.ts b/mod/ConvenientSpiribirds/ConvenientSpiribirds.ts index d3cc2fd..af963e1 100644 --- a/mod/ConvenientSpiribirds/ConvenientSpiribirds.ts +++ b/mod/ConvenientSpiribirds/ConvenientSpiribirds.ts @@ -45,4 +45,26 @@ sdk.hook( } ); + +sdk.hook( + snow.access.ObjectPopMarker.eventIntoAccessable, + (args) => { + let self = sdk.to_managed_object(args[1]) + if (self._Category != snow.access.ObjectPopMarker.MarkerCategory.AccessTypeCreature) { + return; + } + + let wirebuff = self + .get_Parent() + ["getComponent(System.Type)"]( + snow.envCreature.EnvironmentCreatureWireBuff.T().get_runtime_type() + ) as snow.envCreature.EnvironmentCreatureWireBuff; + if (wirebuff) { + wirebuff.noticePopAction(snow.player.PlayerManager.Instance.getMasterPlayerID()) + } + + + } +) + export {}; \ No newline at end of file From e5e4be46481c6bfc18a804a4e9dd8a5a20a92760 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Mon, 8 Aug 2022 12:34:23 +0200 Subject: [PATCH 19/39] Better filter for investigation creation --- mod/Investigations/Investigations.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/mod/Investigations/Investigations.ts b/mod/Investigations/Investigations.ts index aa8d69a..1a8fd22 100644 --- a/mod/Investigations/Investigations.ts +++ b/mod/Investigations/Investigations.ts @@ -1,4 +1,4 @@ -import { snow } from "IL2CPP/IL2CPP"; +import { snow, System } from "IL2CPP/IL2CPP"; import { create_investigation, generate_quest_data, @@ -100,13 +100,22 @@ sdk.hook( } ) -sdk.hook(snow.QuestManager.questEnemyDie, ([_, self, mon]) => { +sdk.hook(snow.QuestManager.questEnemyDie, ([_, self, mon, _dieType]) => { let quest_mgr = sdk.to_managed_object(self); - if (quest_mgr.getQuestRank_Lv() != snow.QuestManager.QuestRank.Master) { return; } + + let dieType = sdk.to_int64(_dieType) + if (dieType > snow.quest.EmEndType.Capture) { + return; + } + let monster = sdk.to_managed_object(mon); + if (!monster.isQuestTargetEnemy()) { + return; + } + let monster_id = monster.get_EnemyType(); let inv = create_investigation(get_player_name(), monster_id) as Investigation From 0443f6bf772272a194a4832e310e1c5c624c7977 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Mon, 8 Aug 2022 20:41:56 +0200 Subject: [PATCH 20/39] Separate touchy wirebugs --- .../ConvenientSpiribirds.ts | 22 ------------- mod/TouchyWirebugs/TouchyWirebugs.ts | 20 +++++++++++ mod/TouchyWirebugs/tsconfig.json | 33 +++++++++++++++++++ 3 files changed, 53 insertions(+), 22 deletions(-) create mode 100644 mod/TouchyWirebugs/TouchyWirebugs.ts create mode 100644 mod/TouchyWirebugs/tsconfig.json diff --git a/mod/ConvenientSpiribirds/ConvenientSpiribirds.ts b/mod/ConvenientSpiribirds/ConvenientSpiribirds.ts index af963e1..d3cc2fd 100644 --- a/mod/ConvenientSpiribirds/ConvenientSpiribirds.ts +++ b/mod/ConvenientSpiribirds/ConvenientSpiribirds.ts @@ -45,26 +45,4 @@ sdk.hook( } ); - -sdk.hook( - snow.access.ObjectPopMarker.eventIntoAccessable, - (args) => { - let self = sdk.to_managed_object(args[1]) - if (self._Category != snow.access.ObjectPopMarker.MarkerCategory.AccessTypeCreature) { - return; - } - - let wirebuff = self - .get_Parent() - ["getComponent(System.Type)"]( - snow.envCreature.EnvironmentCreatureWireBuff.T().get_runtime_type() - ) as snow.envCreature.EnvironmentCreatureWireBuff; - if (wirebuff) { - wirebuff.noticePopAction(snow.player.PlayerManager.Instance.getMasterPlayerID()) - } - - - } -) - export {}; \ No newline at end of file diff --git a/mod/TouchyWirebugs/TouchyWirebugs.ts b/mod/TouchyWirebugs/TouchyWirebugs.ts new file mode 100644 index 0000000..d0d577c --- /dev/null +++ b/mod/TouchyWirebugs/TouchyWirebugs.ts @@ -0,0 +1,20 @@ +import { snow } from "IL2CPP/IL2CPP"; + +sdk.hook( + snow.access.ObjectPopMarker.eventIntoAccessable, + (args) => { + let self = sdk.to_managed_object(args[1]) + if (self._Category != snow.access.ObjectPopMarker.MarkerCategory.AccessTypeCreature) { + return; + } + + let wirebuff = self + .get_Parent() + ["getComponent(System.Type)"]( + snow.envCreature.EnvironmentCreatureWireBuff.T().get_runtime_type() + ) as snow.envCreature.EnvironmentCreatureWireBuff; + if (wirebuff) { + wirebuff.noticePopAction(snow.player.PlayerManager.Instance.getMasterPlayerID()) + } + } +) \ No newline at end of file diff --git a/mod/TouchyWirebugs/tsconfig.json b/mod/TouchyWirebugs/tsconfig.json new file mode 100644 index 0000000..dd5300a --- /dev/null +++ b/mod/TouchyWirebugs/tsconfig.json @@ -0,0 +1,33 @@ +{ + "$schema": "https://raw.githubusercontent.com/TypeScriptToLua/TypeScriptToLua/master/tsconfig-schema.json", + "compilerOptions": { + "lib": [ + "ESNext" + ], + "types": [ + "lua-types/5.4" + ], + "baseUrl": ".", + "paths": { + "IL2CPP/*": [ + "../../IL2CPP/*" + ] + }, + "outDir": "./dist" + }, + "tstl": { + "luaLibImport": "inline", + "luaTarget": "5.3", + "measurePerformance": true, + "noImplicitGlobalVariables": true, + "luaPlugins": [ + { + "name": "../../mod-exporter-plugin/mod-export-path.ts" + } + ] + }, + "include": [ + "./*", + "../../IL2CPP/*" + ] +} \ No newline at end of file From a919dde9c475baa8923b9ba4729ed4c0e9c76ec7 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Mon, 8 Aug 2022 20:42:04 +0200 Subject: [PATCH 21/39] Improve packaging script --- package-mods.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/package-mods.py b/package-mods.py index 34dee10..610b51e 100644 --- a/package-mods.py +++ b/package-mods.py @@ -1,5 +1,5 @@ import os -import shutil +import sys from zipfile import ZipFile os.chdir(os.path.dirname(__file__)) @@ -17,3 +17,15 @@ def zipfolder(foldername: str, zip_path: str): filepath, foldername ))) + + +os.makedirs("output", exist_ok=True) +if len(sys.argv) > 1: + mod_dirs = sys.argv[1:] +else: + mod_dirs = [os.path.join("mod", f) for f in next(os.walk("mod"))[1]] +for m in mod_dirs: + name = os.path.basename(m) + os.system(f"npx tstl -p {m}") + zipfolder(os.path.join(m, "dist"), + os.path.join("output", f"{name}.zip")) From e324a9dba5d8cdcc06a7088c535ab1c2b059689c Mon Sep 17 00:00:00 2001 From: Strackeror Date: Wed, 10 Aug 2022 23:28:00 +0200 Subject: [PATCH 22/39] Prevent auto pickup until remaining time is low --- mod/TouchyWirebugs/TouchyWirebugs.ts | 8 ++++++++ mod/TouchyWirebugs/tsconfig.json | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/mod/TouchyWirebugs/TouchyWirebugs.ts b/mod/TouchyWirebugs/TouchyWirebugs.ts index d0d577c..88a0300 100644 --- a/mod/TouchyWirebugs/TouchyWirebugs.ts +++ b/mod/TouchyWirebugs/TouchyWirebugs.ts @@ -1,5 +1,8 @@ import { snow } from "IL2CPP/IL2CPP"; +// 10 seconds +let MINIMUM_REMAINING_TIME = 10 * 60 + sdk.hook( snow.access.ObjectPopMarker.eventIntoAccessable, (args) => { @@ -8,6 +11,11 @@ sdk.hook( return; } + let player = snow.player.PlayerManager.Instance?.findMasterPlayer(); + if (player.get_HunterWireWildNum() >= 1 && player._HunterWireNumAddTime > MINIMUM_REMAINING_TIME) { + return; + } + let wirebuff = self .get_Parent() ["getComponent(System.Type)"]( diff --git a/mod/TouchyWirebugs/tsconfig.json b/mod/TouchyWirebugs/tsconfig.json index dd5300a..1ad1b42 100644 --- a/mod/TouchyWirebugs/tsconfig.json +++ b/mod/TouchyWirebugs/tsconfig.json @@ -13,7 +13,8 @@ "../../IL2CPP/*" ] }, - "outDir": "./dist" + "outDir": "./dist", + "skipLibCheck": true, }, "tstl": { "luaLibImport": "inline", From 2a001755e126e592ccafde5673d9b23a91dd26ee Mon Sep 17 00:00:00 2001 From: Strackeror Date: Wed, 10 Aug 2022 23:28:09 +0200 Subject: [PATCH 23/39] Fix packaging by folder name --- package-mods.py | 1 + 1 file changed, 1 insertion(+) diff --git a/package-mods.py b/package-mods.py index 610b51e..22875b2 100644 --- a/package-mods.py +++ b/package-mods.py @@ -25,6 +25,7 @@ def zipfolder(foldername: str, zip_path: str): else: mod_dirs = [os.path.join("mod", f) for f in next(os.walk("mod"))[1]] for m in mod_dirs: + m = os.path.normpath(m) name = os.path.basename(m) os.system(f"npx tstl -p {m}") zipfolder(os.path.join(m, "dist"), From 7744fbbaceffc6a59a66ff53a171995800067878 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Sun, 14 Aug 2022 20:05:47 +0200 Subject: [PATCH 24/39] Granular Qurious crafting ininital draft --- IL2CPP/type-filters.json | 1 + .../GranularQuriousCrafting.ts | 260 ++++++++++++++++++ mod/GranularQuriousCrafting/tsconfig.json | 36 +++ 3 files changed, 297 insertions(+) create mode 100644 mod/GranularQuriousCrafting/GranularQuriousCrafting.ts create mode 100644 mod/GranularQuriousCrafting/tsconfig.json diff --git a/IL2CPP/type-filters.json b/IL2CPP/type-filters.json index 4b2d51f..38e5f55 100644 --- a/IL2CPP/type-filters.json +++ b/IL2CPP/type-filters.json @@ -3,6 +3,7 @@ "snow.Snow", "snow.gui.StmGui", "snow.gui.Snow", + "snow.gui.fsm.smithy", "snow.envCreature" ], "type_map_filter": [ diff --git a/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts b/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts new file mode 100644 index 0000000..2a745c9 --- /dev/null +++ b/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts @@ -0,0 +1,260 @@ +import { snow, System, via } from "IL2CPP/IL2CPP"; +import GuiCustomBuildup = snow.gui.fsm.smithy.GuiCustomBuildup; + +function equip_is_craftable_armor(self: GuiCustomBuildup): boolean { + return ( + !self.get_IsWeapon() && + self._PlayerEquipBoxCtrl._EquipBoxGridCursorCtrl.getSelectedEquipInventoryData() + ._CustomEnable + ); +} + +function current_slot_index(self: GuiCustomBuildup): number | undefined { + let index = self._CursorCustomTopMenu.getIndex(); + if (index >= 1 && index <= 7) { + return index - 1; + } + return undefined; +} + +function check_decide(self: GuiCustomBuildup): boolean { + self._CursorCustomTopMenu.get_mouseCtrl().checking(); + return ( + snow.Pad.Instance.app.getDecideButtonTrg() || + snow.gui.StmGuiInput.getDecideMouseEventTrg( + self._CursorCustomTopMenu.get_mouseCtrl(), + snow.gui.StmGuiInput.MouseEventCheckCtrlType.PointingAny, + 0x7fff_ffff + ) || + snow.gui.StmGuiInput.andTrg( + snow.StmInputManager.UI_INPUT.CONF_MENU_DECIDE, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + false, + false + ) + ); +} + +let locked_slots: boolean[]; +let current_inventory_data: snow.data.EquipmentInventoryData; +{ + let self: snow.gui.fsm.smithy.GuiCustomBuildup; + let keepCursor: boolean; + sdk.hook( + snow.gui.fsm.smithy.GuiCustomBuildup.setupTopMenu, + (args) => { + self = sdk.to_managed_object(args[1]); + keepCursor = (sdk.to_int64(args[2]) & 1) == 1; + }, + (retval) => { + if (!equip_is_craftable_armor(self)) { + return retval; + } + if (!keepCursor) { + locked_slots = [false, false, false, false, false, false, false]; + current_inventory_data = + self._PlayerEquipBoxCtrl._EquipBoxGridCursorCtrl.getSelectedEquipInventoryData(); + } + let newCount = self._ListCustomCategory.get_ItemCount() + 7; + self._ListCustomCategory[ + "init(System.UInt32, System.UInt32, System.Int32, System.Int32)" + ](newCount, newCount, 0, 0); + self._ListCustomCategory.set_ItemCount(newCount); + self._ListCustomCategory.set_ItemMax(newCount); + self._CursorCustomTopMenu.updateMenuCursorParam(newCount, newCount); + self._CategoryMenuRemoveIndex += 7; + } + ); +} + +{ + let nextSelf: snow.gui.fsm.smithy.GuiCustomBuildup; + sdk.hook( + snow.gui.fsm.smithy.GuiCustomBuildup.updateTopMenu, + (args) => { + nextSelf = sdk.to_managed_object(args[1]); + }, + (retval) => { + let self = nextSelf; + if (!equip_is_craftable_armor(self)) { + return retval; + } + + let items = self._ListCustomCategory.get_Items(); + for (let i of $range(1, 7)) { + let item = items[i]; + let text = item["getObject(System.String, System.Type)"]( + "pnl_MenuList/txt_menu", + via.gui.Text.T().get_runtime_type() + ) as via.gui.Text; + if (!text) { + continue; + } + if (locked_slots[i - 1]) { + text.set_Message(`Unlock qurious slot ${i}`); + } else { + text.set_Message(`Lock qurious slot ${i}`); + } + } + self._ListCustomCategory.update; + } + ); +} + +sdk.hook(GuiCustomBuildup.updateDetailWindowBySelectTopMenu, (args) => { + let self = sdk.to_managed_object(args[1]); + if (!equip_is_craftable_armor(self)) { + return; + } + let cursorIndex = current_slot_index(self); + if (cursorIndex == undefined) { + return; + } + + let buildupSlot = + self._PlayerEquipBoxCtrl._EquipBoxGridCursorCtrl.getSelectedEquipInventoryData() + ._CustomBuildup[cursorIndex]; + self._TextDetailWindowMenu.set_Message(`Lock qurious slot`); + self._TextDetailWindowExplain.set_Message( + `Currently in slot: ${buildupSlot?._Id}` + ); + return sdk.PreHookResult.SKIP_ORIGINAL; +}); + +sdk.hook(GuiCustomBuildup.routineSelectTopMenu, (args) => { + let self = sdk.to_managed_object(args[1]); + if (!equip_is_craftable_armor(self)) { + return; + } + + let slotIndex = current_slot_index(self); + if (slotIndex == undefined) { + return; + } + + if (check_decide(self)) { + locked_slots[slotIndex] = !locked_slots[slotIndex]; + self.updateDetailWindowBySelectTopMenu(); + self.updateTopMenu(); + return sdk.PreHookResult.SKIP_ORIGINAL; + } +}); + + +{ + let SKILL_MINUS_ID = 149; + let SLOT_PLUS_1 = 139; + let SLOT_PLUS_2 = 140; + let SLOT_PLUS_3 = 141; + + let recurse_guard = false; + let ret: any; + sdk.hook( + snow.data.ArmorCustomBuildupData.createResult, + (args) => { + if (recurse_guard) { + return; + } + let self = sdk.to_managed_object(args[1]); + let cost = sdk.to_int64(args[2]) & 0xffff_ffff; + let slotBlank = sdk.to_int64(args[3]) & 0xffff_ffff; + let skillList = sdk.to_managed_object(args[4]); + + let final_buildups: { + [t: number]: snow.data.CustomBuildupResultData; + } = {}; + + let new_cost = cost; + let armor_data = current_inventory_data.getArmorData(); + let minimum_slot_count = 0; + for (let i of $range(0, 6)) { + if (locked_slots[i]) { + log.info(`Locked slot ${i}`); + let buildup = armor_data.get_CustomBuildupResult()[i]; + switch (buildup.get_Id()) { + // If a minus skill is locked, remove it from the skill list + case SKILL_MINUS_ID: + for (let i of $range(0, skillList.mSize - 1)) { + if ( + skillList.get_Item(i).get_EquipSkillId() == + buildup.get_PlSkillId() + ) { + skillList.RemoveAt(i); + break; + } + } + break; + + // If a slot increase is locked, substract its value from the possible blank slots + case SLOT_PLUS_1: + slotBlank -= 1; + break; + case SLOT_PLUS_2: + slotBlank -= 2; + break; + case SLOT_PLUS_3: + slotBlank -= 3; + break; + } + // Substract cost of the buildup + new_cost -= buildup.get_Cost(); + final_buildups[i] = buildup; + + // We need at least all the locked slots to be occupied in the result array + minimum_slot_count = i + 1; + } + } + + // We reroll results until we have enough slots to fill everything + let result: ReturnType; + do { + recurse_guard = true; + result = self.createResult(new_cost, slotBlank, skillList, false); + recurse_guard = false; + } while (result.get_Count() < minimum_slot_count) + + let result_count = result.get_Count(); + + for (let i of $range(0, result_count - 1)) { + for (let j of $range(0, 6)) { + if (!(j in final_buildups)) { + final_buildups[j] = result[i] + break; + } + } + } + + log.info("found result"); + log.info(`${result.get_Count()}`); + for (let i of $range(0, result_count - 1)) { + if (i in final_buildups) { + result[i] = final_buildups[i]; + } + log.info( + `${result[i].get_Id()}, skill: ${result[i].get_PlSkillId()}, ${result[ + i + ].ToString()}` + ); + } + + ret = sdk.to_ptr(result); + return sdk.PreHookResult.SKIP_ORIGINAL; + }, + (retval) => { + if (ret) { + let nret = ret; + ret = undefined + return nret; + } + return retval; + } + ); +} diff --git a/mod/GranularQuriousCrafting/tsconfig.json b/mod/GranularQuriousCrafting/tsconfig.json new file mode 100644 index 0000000..9467aab --- /dev/null +++ b/mod/GranularQuriousCrafting/tsconfig.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://raw.githubusercontent.com/TypeScriptToLua/TypeScriptToLua/master/tsconfig-schema.json", + "compilerOptions": { + "lib": [ + "ESNext" + ], + "types": [ + "lua-types/5.4" + ], + "baseUrl": ".", + "paths": { + "IL2CPP/*": [ + "../../IL2CPP/*" + ] + }, + "outDir": "./dist", + "skipLibCheck": true, + "noImplicitAny": true, + "target": "ES2020" + }, + "tstl": { + "luaLibImport": "inline", + "luaTarget": "5.3", + "measurePerformance": true, + "noImplicitGlobalVariables": true, + "luaPlugins": [ + { + "name": "../../mod-exporter-plugin/mod-export-path.ts" + } + ] + }, + "include": [ + "./*", + "../../IL2CPP/*" + ] +} \ No newline at end of file From 8a30398a83d5eedaf4cce718b715f78380036008 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Mon, 15 Aug 2022 19:29:53 +0200 Subject: [PATCH 25/39] Improvements to QuriousCrafting --- .vscode/settings.json | 6 +- .../GranularQuriousCrafting.ts | 260 +++++++++++------- 2 files changed, 171 insertions(+), 95 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 7bf4c24..2430c72 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,5 +2,9 @@ "Lua.diagnostics.globals": [ "sdk" ], - "typescript.preferences.importModuleSpecifier": "non-relative" + "typescript.preferences.importModuleSpecifier": "non-relative", + "prettier.printWidth": 120, + "editor.rulers": [ + 120 + ] } \ No newline at end of file diff --git a/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts b/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts index 2a745c9..2ccef2e 100644 --- a/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts +++ b/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts @@ -1,18 +1,68 @@ import { snow, System, via } from "IL2CPP/IL2CPP"; import GuiCustomBuildup = snow.gui.fsm.smithy.GuiCustomBuildup; +let NO_ELEMENT = snow.data.DataDef.ArmorElementRegistTypes.Max; +let ELEMENT_ARRAY = ["Fire", "Water", "Thunder", "Ice", "Dragon"]; +function custom_buildup_description(buildup: snow.data.CustomBuildupResultData): string { + if (buildup.get_IsDefBounus()) { + let sign = buildup.get_Value() > 0 ? "+" : ""; + return `Def ${sign}${buildup.get_Value()}`; + } + + if (buildup.get_RegElement() < NO_ELEMENT) { + let sign = buildup.get_Value() > 0 ? "+" : ""; + return `${ELEMENT_ARRAY[buildup.get_RegElement()]} Res ${sign}${buildup.get_Value()}`; + } + + if (buildup.get_IsSlotBonus()) { + return `Slot +${buildup.get_Value()}`; + } + + if (buildup.get_IsSkillAddBonus()) { + let skillData = snow.data.SkillDataManager.getBaseData(buildup.get_PlSkillId()); + return `+${skillData.get_Name()}`; + } + + if (buildup.get_IsSkillSubBonus()) { + let skillData = snow.data.SkillDataManager.getBaseData(buildup.get_PlSkillId()); + return `-${skillData.get_Name()}`; + } + return `Unrecognized`; +} + +// Static data +let locked_slots: boolean[]; +let current_inventory_data: snow.data.EquipmentInventoryData; +let buildup_count = 0; + + +function buildup_data() { + return current_inventory_data.getArmorData().get_CustomBuildupResult(); +} + +function remaining_cost(): number { + let cost = current_inventory_data.getArmorBaseData().get_CustomCost() + for (let i = 0; i < current_inventory_data.get_CustomCount(); ++i) { + if (locked_slots[i]) { + cost -= buildup_data()[i].get_Cost(); + } + } + return cost +} + function equip_is_craftable_armor(self: GuiCustomBuildup): boolean { return ( !self.get_IsWeapon() && - self._PlayerEquipBoxCtrl._EquipBoxGridCursorCtrl.getSelectedEquipInventoryData() - ._CustomEnable + self._PlayerEquipBoxCtrl._EquipBoxGridCursorCtrl.getSelectedEquipInventoryData()._CustomEnable ); } -function current_slot_index(self: GuiCustomBuildup): number | undefined { +function current_buildup_index(self: GuiCustomBuildup): number | undefined { let index = self._CursorCustomTopMenu.getIndex(); - if (index >= 1 && index <= 7) { - return index - 1; + let begin = 1; + let end = begin + buildup_count; + if (index >= begin && index < end) { + return index - begin; } return undefined; } @@ -26,25 +76,10 @@ function check_decide(self: GuiCustomBuildup): boolean { snow.gui.StmGuiInput.MouseEventCheckCtrlType.PointingAny, 0x7fff_ffff ) || - snow.gui.StmGuiInput.andTrg( - snow.StmInputManager.UI_INPUT.CONF_MENU_DECIDE, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - false, - false - ) + snow.gui.StmGuiInput.andTrg(snow.StmInputManager.UI_INPUT.CONF_MENU_DECIDE, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, false) ); } -let locked_slots: boolean[]; -let current_inventory_data: snow.data.EquipmentInventoryData; { let self: snow.gui.fsm.smithy.GuiCustomBuildup; let keepCursor: boolean; @@ -55,22 +90,34 @@ let current_inventory_data: snow.data.EquipmentInventoryData; keepCursor = (sdk.to_int64(args[2]) & 1) == 1; }, (retval) => { + if (!keepCursor) { + locked_slots = [false, false, false, false, false, false, false]; + } + if (!equip_is_craftable_armor(self)) { return retval; } - if (!keepCursor) { - locked_slots = [false, false, false, false, false, false, false]; - current_inventory_data = - self._PlayerEquipBoxCtrl._EquipBoxGridCursorCtrl.getSelectedEquipInventoryData(); + current_inventory_data = self._PlayerEquipBoxCtrl._EquipBoxGridCursorCtrl.getSelectedEquipInventoryData(); + + buildup_count = 0 + for (let i = 0; i < 7; ++i) { + if (buildup_data()[i].get_Id() == 0) { + break; + } + buildup_count += 1 } - let newCount = self._ListCustomCategory.get_ItemCount() + 7; - self._ListCustomCategory[ - "init(System.UInt32, System.UInt32, System.Int32, System.Int32)" - ](newCount, newCount, 0, 0); - self._ListCustomCategory.set_ItemCount(newCount); - self._ListCustomCategory.set_ItemMax(newCount); - self._CursorCustomTopMenu.updateMenuCursorParam(newCount, newCount); - self._CategoryMenuRemoveIndex += 7; + + let new_count = self._ListCustomCategory.get_ItemCount() + buildup_count; + self._ListCustomCategory["init(System.UInt32, System.UInt32, System.Int32, System.Int32)"]( + new_count, + new_count, + 0, + 0 + ); + self._ListCustomCategory.set_ItemCount(new_count); + self._ListCustomCategory.set_ItemMax(new_count); + self._CursorCustomTopMenu.updateMenuCursorParam(new_count, new_count); + self._CategoryMenuRemoveIndex += buildup_count; } ); } @@ -89,23 +136,23 @@ let current_inventory_data: snow.data.EquipmentInventoryData; } let items = self._ListCustomCategory.get_Items(); - for (let i of $range(1, 7)) { - let item = items[i]; - let text = item["getObject(System.String, System.Type)"]( + for (let i = 0; i < buildup_count; ++i) { + let text = items[i + 1]["getObject(System.String, System.Type)"]( "pnl_MenuList/txt_menu", via.gui.Text.T().get_runtime_type() ) as via.gui.Text; if (!text) { continue; } - if (locked_slots[i - 1]) { - text.set_Message(`Unlock qurious slot ${i}`); + let buildup = buildup_data()[i]; + let description = custom_buildup_description(buildup); + if (locked_slots[i]) { + text.set_Message(`Unlock ${description} (Cost:${buildup.get_Cost()})`) } else { - text.set_Message(`Lock qurious slot ${i}`); + text.set_Message(`Lock ${description} (Cost:${buildup.get_Cost()})`) } } - self._ListCustomCategory.update; - } + } ); } @@ -114,18 +161,17 @@ sdk.hook(GuiCustomBuildup.updateDetailWindowBySelectTopMenu, (args) => { if (!equip_is_craftable_armor(self)) { return; } - let cursorIndex = current_slot_index(self); - if (cursorIndex == undefined) { + let buildup_index = current_buildup_index(self); + if (buildup_index == undefined) { return; } - let buildupSlot = - self._PlayerEquipBoxCtrl._EquipBoxGridCursorCtrl.getSelectedEquipInventoryData() - ._CustomBuildup[cursorIndex]; + let buildupSlot = buildup_data()[buildup_index] self._TextDetailWindowMenu.set_Message(`Lock qurious slot`); self._TextDetailWindowExplain.set_Message( - `Currently in slot: ${buildupSlot?._Id}` - ); +`Currently in slot: ${custom_buildup_description(buildupSlot)} +Available Cost: ${remaining_cost()}` + ); return sdk.PreHookResult.SKIP_ORIGINAL; }); @@ -135,27 +181,51 @@ sdk.hook(GuiCustomBuildup.routineSelectTopMenu, (args) => { return; } - let slotIndex = current_slot_index(self); - if (slotIndex == undefined) { + let buildup_index = current_buildup_index(self); + if (buildup_index == undefined) { return; } if (check_decide(self)) { - locked_slots[slotIndex] = !locked_slots[slotIndex]; + // Logic to prevent locking slots that would result into negative costs + // Sending a negative cost to the rolling function gives invalid results + let cost = buildup_data()[buildup_index].get_Cost(); + if (locked_slots[buildup_index]) { + cost *= -1 + } + if (cost < remaining_cost()) { + locked_slots[buildup_index] = !locked_slots[buildup_index]; + } + + self.updateMaterialListWindow() self.updateDetailWindowBySelectTopMenu(); self.updateTopMenu(); return sdk.PreHookResult.SKIP_ORIGINAL; } }); - { - let SKILL_MINUS_ID = 149; - let SLOT_PLUS_1 = 139; - let SLOT_PLUS_2 = 140; - let SLOT_PLUS_3 = 141; + let args; + sdk.hook(snow.data.CustomBuildupModule.getArmorMaterialData, (a) => { + args = a; + }, + (retval) => { + if (locked_slots) { + let param = sdk.to_managed_object(retval).MemberwiseClone() as snow.data.CustomBuildupArmorMaterialUserData.Param; + for (let b of locked_slots) { + if (b) { + param._MaterialCategoryNum *= 2; + } + } + return sdk.to_ptr(param); + } + return retval; + }); +} +{ let recurse_guard = false; + let ret: any; sdk.hook( snow.data.ArmorCustomBuildupData.createResult, @@ -173,37 +243,26 @@ sdk.hook(GuiCustomBuildup.routineSelectTopMenu, (args) => { } = {}; let new_cost = cost; - let armor_data = current_inventory_data.getArmorData(); let minimum_slot_count = 0; - for (let i of $range(0, 6)) { + for (let i = 0; i < skillList.mSize; ++i) { + log.info(`Armor skill ${i}: ${skillList.get_Item(i).get_Name()} ${skillList.get_Item(i).getLv(9)}`); + } + + let forbidden_minus_skills: {[skillId: number]: true} = {} + for (let i = 0; i < buildup_count; ++i) { if (locked_slots[i]) { log.info(`Locked slot ${i}`); - let buildup = armor_data.get_CustomBuildupResult()[i]; - switch (buildup.get_Id()) { - // If a minus skill is locked, remove it from the skill list - case SKILL_MINUS_ID: - for (let i of $range(0, skillList.mSize - 1)) { - if ( - skillList.get_Item(i).get_EquipSkillId() == - buildup.get_PlSkillId() - ) { - skillList.RemoveAt(i); - break; - } - } - break; - - // If a slot increase is locked, substract its value from the possible blank slots - case SLOT_PLUS_1: - slotBlank -= 1; - break; - case SLOT_PLUS_2: - slotBlank -= 2; - break; - case SLOT_PLUS_3: - slotBlank -= 3; - break; + let buildup = buildup_data()[i]; + + // If a minus skill is locked, forbid it + if (buildup.get_IsSkillSubBonus()) { + forbidden_minus_skills[buildup.get_PlSkillId()] = true; } + + if (buildup.get_IsSlotBonus()) { + slotBlank -= buildup.get_Value(); + } + // Substract cost of the buildup new_cost -= buildup.get_Cost(); final_buildups[i] = buildup; @@ -214,19 +273,36 @@ sdk.hook(GuiCustomBuildup.routineSelectTopMenu, (args) => { } // We reroll results until we have enough slots to fill everything + recurse_guard = true; + let result: ReturnType; do { - recurse_guard = true; result = self.createResult(new_cost, slotBlank, skillList, false); - recurse_guard = false; - } while (result.get_Count() < minimum_slot_count) + if (result.get_Count() == 0) return; + + let ok = true; + // Reroll if we have duplicate minus skills + for (let i = 0; i < result.get_Length(); ++i) { + if (result[i].get_IsSkillSubBonus() && forbidden_minus_skills[result[i].get_PlSkillId()]) { + ok = false; + } + } + + // Reroll if we don't have enough slots + if (result.get_Count() < minimum_slot_count) ok = false; + + if (ok) break; + } while (true); + + recurse_guard = false; + let result_count = result.get_Count(); for (let i of $range(0, result_count - 1)) { - for (let j of $range(0, 6)) { + for (let j of $range(0, result_count - 1)) { if (!(j in final_buildups)) { - final_buildups[j] = result[i] + final_buildups[j] = result[i]; break; } } @@ -238,11 +314,7 @@ sdk.hook(GuiCustomBuildup.routineSelectTopMenu, (args) => { if (i in final_buildups) { result[i] = final_buildups[i]; } - log.info( - `${result[i].get_Id()}, skill: ${result[i].get_PlSkillId()}, ${result[ - i - ].ToString()}` - ); + log.info(`${result[i].get_Id()}, skill: ${result[i].get_PlSkillId()}, ${result[i].ToString()}`); } ret = sdk.to_ptr(result); @@ -251,7 +323,7 @@ sdk.hook(GuiCustomBuildup.routineSelectTopMenu, (args) => { (retval) => { if (ret) { let nret = ret; - ret = undefined + ret = undefined; return nret; } return retval; From 72daf910f6a144648f449bdf84efdb3b1a76cdc0 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Mon, 15 Aug 2022 23:02:30 +0200 Subject: [PATCH 26/39] Support for anomaly investigations --- mod/MonsterJournalPage/MonsterJournalPage.ts | 38 ++++++++++++-------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/mod/MonsterJournalPage/MonsterJournalPage.ts b/mod/MonsterJournalPage/MonsterJournalPage.ts index 5144bb7..28ec06b 100644 --- a/mod/MonsterJournalPage/MonsterJournalPage.ts +++ b/mod/MonsterJournalPage/MonsterJournalPage.ts @@ -7,29 +7,39 @@ function get_current_target_monsters(): snow.enemy.EnemyDef.EmTypes[] { } let data = current_quest.get_RawNormal(); - if (!data) { - return []; - } - - if (data._TargetType.Get(0) == snow.quest.QuestTargetType.AllMainEnemy) { + if (data) + { let ret = []; - for (let i = 0; i < data._BossEmType.get_Count(); ++i) { - let em = data._BossEmType.Get(i); + if (data._TargetType.Get(0) == snow.quest.QuestTargetType.AllMainEnemy) { + for (let i = 0; i < data._BossEmType.get_Count(); ++i) { + let em = data._BossEmType.Get(i); + if (em != 0) { + ret.push(data._BossEmType.Get(i)); + } + } + return ret; + } + + for (let i = 0; i < data._TgtEmType.get_Count(); ++i) { + let em = data._TgtEmType.Get(i); if (em != 0) { - ret.push(data._BossEmType.Get(i)); + ret.push(data._TgtEmType.Get(i)); } } return ret; } - let ret = []; - for (let i = 0; i < data._TgtEmType.get_Count(); ++i) { - let em = data._TgtEmType.Get(i); - if (em != 0) { - ret.push(data._TgtEmType.Get(i)); + let mystery = current_quest.get_RandomMystery() + if (mystery) + { + let ret: number[] = [] + for (let i = 0; i < mystery._HuntTargetNum; ++i) { + ret.push(mystery._BossEmType.Get(i)); } + return ret; + } - return ret; + return []; } let current_idx = 0; From 3f484359f2bcd684757c177f10ab9d85c63c932f Mon Sep 17 00:00:00 2001 From: Strackeror Date: Mon, 15 Aug 2022 23:26:09 +0200 Subject: [PATCH 27/39] Quick fix to avoid stack params and readability --- mod/GranularQuriousCrafting/GranularQuriousCrafting.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts b/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts index 2ccef2e..cf73348 100644 --- a/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts +++ b/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts @@ -147,9 +147,9 @@ function check_decide(self: GuiCustomBuildup): boolean { let buildup = buildup_data()[i]; let description = custom_buildup_description(buildup); if (locked_slots[i]) { - text.set_Message(`Unlock ${description} (Cost:${buildup.get_Cost()})`) + text.set_Message(`${description} (Cost:${buildup.get_Cost()}) [Locked]`) } else { - text.set_Message(`Lock ${description} (Cost:${buildup.get_Cost()})`) + text.set_Message(`${description} (Cost:${buildup.get_Cost()})`) } } } @@ -235,8 +235,11 @@ sdk.hook(GuiCustomBuildup.routineSelectTopMenu, (args) => { } let self = sdk.to_managed_object(args[1]); let cost = sdk.to_int64(args[2]) & 0xffff_ffff; + let slotBlank = sdk.to_int64(args[3]) & 0xffff_ffff; - let skillList = sdk.to_managed_object(args[4]); + let skillList = current_inventory_data.getArmorBaseData().get_AllSkillDataList(); + // let skillList = sdk.to_managed_object(args[4]); + let final_buildups: { [t: number]: snow.data.CustomBuildupResultData; From 06c59c6cfc40d1be57086ad8d46cd1406eb3b4bd Mon Sep 17 00:00:00 2001 From: Strackeror Date: Wed, 17 Aug 2022 12:55:37 +0200 Subject: [PATCH 28/39] Lock icon for curious crafting --- .../GranularQuriousCrafting.ts | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts b/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts index cf73348..a2bb43e 100644 --- a/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts +++ b/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts @@ -146,11 +146,23 @@ function check_decide(self: GuiCustomBuildup): boolean { } let buildup = buildup_data()[i]; let description = custom_buildup_description(buildup); - if (locked_slots[i]) { - text.set_Message(`${description} (Cost:${buildup.get_Cost()}) [Locked]`) - } else { - text.set_Message(`${description} (Cost:${buildup.get_Cost()})`) + + text.set_Message(`${description} Cost:${buildup.get_Cost()}`); + let panel = items[i + 1]["getObject(System.String, System.Type)"]( + "pnl_MenuList/pnl_Status", + via.gui.Panel.T().get_runtime_type() + ) as via.gui.Panel; + if (panel) { + if (locked_slots[i]) { + panel.set_PlayState("LOCK"); + panel.set_Visible(true); + } else { + panel.set_PlayState("DEFAULT"); + panel.set_Visible(false); + } } + snow.gui.SnowGuiCommonUtility.reqSe(0xf4b6879b); + } } ); From 39d6d5edd9b4b6d8b0c4d0c30367ba9b31d66f23 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Fri, 19 Aug 2022 00:35:08 +0200 Subject: [PATCH 29/39] Improvements for granular qurious crafting - More forgiving cost increase - Improved augment generation - Improved user interface (LOCKS!) --- .../GranularQuriousCrafting.ts | 117 ++++++++---------- 1 file changed, 55 insertions(+), 62 deletions(-) diff --git a/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts b/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts index a2bb43e..d902e4e 100644 --- a/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts +++ b/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts @@ -6,26 +6,26 @@ let ELEMENT_ARRAY = ["Fire", "Water", "Thunder", "Ice", "Dragon"]; function custom_buildup_description(buildup: snow.data.CustomBuildupResultData): string { if (buildup.get_IsDefBounus()) { let sign = buildup.get_Value() > 0 ? "+" : ""; - return `Def ${sign}${buildup.get_Value()}`; + return `${sign}${buildup.get_Value()} Defense`; } if (buildup.get_RegElement() < NO_ELEMENT) { let sign = buildup.get_Value() > 0 ? "+" : ""; - return `${ELEMENT_ARRAY[buildup.get_RegElement()]} Res ${sign}${buildup.get_Value()}`; + return `${sign}${buildup.get_Value()} ${ELEMENT_ARRAY[buildup.get_RegElement()]} Res`; } if (buildup.get_IsSlotBonus()) { - return `Slot +${buildup.get_Value()}`; + return `+${buildup.get_Value()} Slot`; } if (buildup.get_IsSkillAddBonus()) { let skillData = snow.data.SkillDataManager.getBaseData(buildup.get_PlSkillId()); - return `+${skillData.get_Name()}`; + return `+1 ${skillData.get_Name()}`; } if (buildup.get_IsSkillSubBonus()) { let skillData = snow.data.SkillDataManager.getBaseData(buildup.get_PlSkillId()); - return `-${skillData.get_Name()}`; + return `-1 ${skillData.get_Name()}`; } return `Unrecognized`; } @@ -42,7 +42,7 @@ function buildup_data() { function remaining_cost(): number { let cost = current_inventory_data.getArmorBaseData().get_CustomCost() - for (let i = 0; i < current_inventory_data.get_CustomCount(); ++i) { + for (let i = 0; i < buildup_count; ++i) { if (locked_slots[i]) { cost -= buildup_data()[i].get_Cost(); } @@ -80,6 +80,36 @@ function check_decide(self: GuiCustomBuildup): boolean { ); } +function check_valid(armor: snow.data.ArmorData, buildups: System.Array.Generic) { + let base_data = armor.get_BaseData(); + let skill_data = base_data.get_AllSkillDataList(); + let skill_levels: { [skill_id: number]: number; _objTag: "" } = { _objTag: "" }; + + for (let i = 0; i < skill_data.get_Count(); ++i) { + skill_levels[skill_data.get_Item(i).get_EquipSkillId()] = skill_data.get_Item(i).get_TotalLv(); + } + + let budget = base_data.get_CustomCost(); + for (let i = 0; i < buildups.get_Count(); ++i) { + let buildup = buildups[i] + budget -= buildup.get_Cost(); + if (budget < 0) { + return false; + } + + if (buildup.get_IsSkillSubBonus()) { + let skill = buildup.get_PlSkillId(); + if (skill in skill_levels) { + if (skill_levels[skill] == 0) { + return false; + } + skill_levels[skill] -= 1; + } + } + } + return true; +} + { let self: snow.gui.fsm.smithy.GuiCustomBuildup; let keepCursor: boolean; @@ -99,13 +129,7 @@ function check_decide(self: GuiCustomBuildup): boolean { } current_inventory_data = self._PlayerEquipBoxCtrl._EquipBoxGridCursorCtrl.getSelectedEquipInventoryData(); - buildup_count = 0 - for (let i = 0; i < 7; ++i) { - if (buildup_data()[i].get_Id() == 0) { - break; - } - buildup_count += 1 - } + buildup_count = current_inventory_data.getArmorData().get_CustomBuildupResultNum(); let new_count = self._ListCustomCategory.get_ItemCount() + buildup_count; self._ListCustomCategory["init(System.UInt32, System.UInt32, System.Int32, System.Int32)"]( @@ -147,7 +171,7 @@ function check_decide(self: GuiCustomBuildup): boolean { let buildup = buildup_data()[i]; let description = custom_buildup_description(buildup); - text.set_Message(`${description} Cost:${buildup.get_Cost()}`); + text.set_Message(`${description} [${buildup.get_Cost()}]`); let panel = items[i + 1]["getObject(System.String, System.Type)"]( "pnl_MenuList/pnl_Status", via.gui.Panel.T().get_runtime_type() @@ -182,7 +206,7 @@ sdk.hook(GuiCustomBuildup.updateDetailWindowBySelectTopMenu, (args) => { self._TextDetailWindowMenu.set_Message(`Lock qurious slot`); self._TextDetailWindowExplain.set_Message( `Currently in slot: ${custom_buildup_description(buildupSlot)} -Available Cost: ${remaining_cost()}` +Available Budget: ${remaining_cost()}` ); return sdk.PreHookResult.SKIP_ORIGINAL; }); @@ -224,11 +248,14 @@ sdk.hook(GuiCustomBuildup.routineSelectTopMenu, (args) => { (retval) => { if (locked_slots) { let param = sdk.to_managed_object(retval).MemberwiseClone() as snow.data.CustomBuildupArmorMaterialUserData.Param; + let addCost = 0; for (let b of locked_slots) { if (b) { - param._MaterialCategoryNum *= 2; + if (addCost == 0) addCost = 10; + addCost *= 2; } } + param._MaterialCategoryNum += addCost; return sdk.to_ptr(param); } return retval; @@ -253,85 +280,51 @@ sdk.hook(GuiCustomBuildup.routineSelectTopMenu, (args) => { // let skillList = sdk.to_managed_object(args[4]); - let final_buildups: { - [t: number]: snow.data.CustomBuildupResultData; - } = {}; - let new_cost = cost; let minimum_slot_count = 0; - for (let i = 0; i < skillList.mSize; ++i) { - log.info(`Armor skill ${i}: ${skillList.get_Item(i).get_Name()} ${skillList.get_Item(i).getLv(9)}`); - } - let forbidden_minus_skills: {[skillId: number]: true} = {} for (let i = 0; i < buildup_count; ++i) { if (locked_slots[i]) { - log.info(`Locked slot ${i}`); let buildup = buildup_data()[i]; - // If a minus skill is locked, forbid it - if (buildup.get_IsSkillSubBonus()) { - forbidden_minus_skills[buildup.get_PlSkillId()] = true; - } - if (buildup.get_IsSlotBonus()) { slotBlank -= buildup.get_Value(); } // Substract cost of the buildup new_cost -= buildup.get_Cost(); - final_buildups[i] = buildup; - // We need at least all the locked slots to be occupied in the result array - minimum_slot_count = i + 1; + // We reroll results until we have enough slots to fit locked slots in their place + minimum_slot_count = i + 1 } } - // We reroll results until we have enough slots to fill everything recurse_guard = true; let result: ReturnType; do { result = self.createResult(new_cost, slotBlank, skillList, false); + if (result.get_Count() == 0) return; + // Reroll if we don't have enough slots + if (result.get_Count() < minimum_slot_count) continue; - let ok = true; - // Reroll if we have duplicate minus skills - for (let i = 0; i < result.get_Length(); ++i) { - if (result[i].get_IsSkillSubBonus() && forbidden_minus_skills[result[i].get_PlSkillId()]) { - ok = false; + for (let i = 0; i < buildup_count; ++i) { + if (locked_slots[i]) { + result[i] = buildup_data()[i] } } - - // Reroll if we don't have enough slots - if (result.get_Count() < minimum_slot_count) ok = false; - - if (ok) break; + if (!check_valid(current_inventory_data.getArmorData(), result)) continue; + break; } while (true); recurse_guard = false; - - let result_count = result.get_Count(); - - for (let i of $range(0, result_count - 1)) { - for (let j of $range(0, result_count - 1)) { - if (!(j in final_buildups)) { - final_buildups[j] = result[i]; - break; - } - } - } - log.info("found result"); log.info(`${result.get_Count()}`); - for (let i of $range(0, result_count - 1)) { - if (i in final_buildups) { - result[i] = final_buildups[i]; - } - log.info(`${result[i].get_Id()}, skill: ${result[i].get_PlSkillId()}, ${result[i].ToString()}`); + for (let i = 0; i < result.get_Count(); ++i) { + log.info(`${custom_buildup_description(result[i])} (${result[i].get_Cost()})`); } - ret = sdk.to_ptr(result); return sdk.PreHookResult.SKIP_ORIGINAL; }, From 1ac549c9882e6c930fe54c2b4b448581fd5d6e5e Mon Sep 17 00:00:00 2001 From: Strackeror Date: Fri, 19 Aug 2022 00:45:34 +0200 Subject: [PATCH 30/39] Filter tweak --- IL2CPP/type-filters.json | 1 + 1 file changed, 1 insertion(+) diff --git a/IL2CPP/type-filters.json b/IL2CPP/type-filters.json index 38e5f55..8b741a1 100644 --- a/IL2CPP/type-filters.json +++ b/IL2CPP/type-filters.json @@ -4,6 +4,7 @@ "snow.gui.StmGui", "snow.gui.Snow", "snow.gui.fsm.smithy", + "snow.gui.fsm.itembox", "snow.envCreature" ], "type_map_filter": [ From 9eacc8c7c9da107935067252dd7c44cb090acec6 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Fri, 19 Aug 2022 00:48:33 +0200 Subject: [PATCH 31/39] Expanded item shop mod --- mod/AddToItemShop/AddToItemShop.ts | 76 ++++++++++++++++++++++++++++++ mod/AddToItemShop/ItemList.json | 6 +++ mod/AddToItemShop/tsconfig.json | 38 +++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 mod/AddToItemShop/AddToItemShop.ts create mode 100644 mod/AddToItemShop/ItemList.json create mode 100644 mod/AddToItemShop/tsconfig.json diff --git a/mod/AddToItemShop/AddToItemShop.ts b/mod/AddToItemShop/AddToItemShop.ts new file mode 100644 index 0000000..f15c838 --- /dev/null +++ b/mod/AddToItemShop/AddToItemShop.ts @@ -0,0 +1,76 @@ +import { snow, System } from "IL2CPP/IL2CPP"; +import * as ITEM_LIST from "./ItemList.json" + +interface Iterable { + get_Item(i: number): T; + get_Count(): number; +} + +function* il_iter(obj: Iterable) { + for (let i = 0; i < obj.get_Count(); ++i) { + yield obj.get_Item(i); + } +} + +function create_array(type: RETypeDefinition, table: T[]) { + let array = sdk.create_managed_array(type.get_full_name(), table.length); + for (let i = 0; i < table.length; ++i) { + array.Set(i, table[i]); + } + return array; +} + + +function argosy_item_list(): number[] { + let list = snow.facility.TradeCenterFacility.Instance.get_TradeFunc()._TradeUserData._Param; + let ret: number[] = [] + for (let data of il_iter(list)) { + ret.push(data._ItemId); + } + return ret; +} + +function create_item(itemId: number, index: number): snow.data.ItemShopDisplayUserData.Param { + let item_data = snow.data.ItemShopDisplayUserData.Param.T().create_instance(); + item_data._Id = itemId; + item_data._SortId = index; + item_data._FlagIndex = index; + item_data._IsBargainObject = true; + item_data._IsUnlockAfterAlchemy = false; + item_data._HallProgress = 1; + item_data._VillageProgress = 1; + item_data._MRProgress = 0; + return item_data; +} + +function addItems(self: snow.data.ItemShopFacility) { + + let count = self._DisplayData._Param.get_Count(); + let data: snow.data.ItemShopDisplayUserData.Param[] = [] + + for (let id of argosy_item_list()) { + data.push(create_item(id, count)) + count += 1; + } + for (let id of ITEM_LIST.map(n => tonumber(n, 0x10))) { + data.push(create_item(id, count)) + count += 1; + } + + self._DisplayData._Param = create_array(snow.data.ItemShopDisplayUserData.Param.T(), [ + ...il_iter(self._DisplayData._Param), + ...data, + ]); +} + +{ + let self: snow.data.ItemShopFacility; + sdk.hook( + snow.data.ItemShopFacility.initialize, + (args) => { + self = sdk.to_managed_object(args[1]); + addItems(self) + }, + + ); +} diff --git a/mod/AddToItemShop/ItemList.json b/mod/AddToItemShop/ItemList.json new file mode 100644 index 0000000..de90bf0 --- /dev/null +++ b/mod/AddToItemShop/ItemList.json @@ -0,0 +1,6 @@ +[ + "041001D6", + "041001D5", + "041001F3", + "0410030E" +] \ No newline at end of file diff --git a/mod/AddToItemShop/tsconfig.json b/mod/AddToItemShop/tsconfig.json new file mode 100644 index 0000000..1e2e8f6 --- /dev/null +++ b/mod/AddToItemShop/tsconfig.json @@ -0,0 +1,38 @@ +{ + "$schema": "https://raw.githubusercontent.com/TypeScriptToLua/TypeScriptToLua/master/tsconfig-schema.json", + "compilerOptions": { + "lib": [ + "ESNext" + ], + "types": [ + "lua-types/5.4" + ], + "baseUrl": ".", + "paths": { + "IL2CPP/*": [ + "../../IL2CPP/*" + ] + }, + "outDir": "./dist", + "skipLibCheck": true, + "noImplicitAny": true, + "target": "ES2020", + "moduleResolution": "node", + "resolveJsonModule": true + }, + "tstl": { + "luaLibImport": "inline", + "luaTarget": "5.3", + "measurePerformance": true, + "noImplicitGlobalVariables": true, + "luaPlugins": [ + { + "name": "../../mod-exporter-plugin/mod-export-path.ts" + } + ] + }, + "include": [ + "./*", + "../../IL2CPP/*" + ] +} \ No newline at end of file From 6b8dce784de3287b0920d3536eb8d4c42d12cf58 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Mon, 22 Aug 2022 18:03:38 +0200 Subject: [PATCH 32/39] Improvements to monster journal: - Key prompts - Monster state switch --- IL2CPP/type-filters.json | 1 + mod/MonsterJournalPage/MonsterJournalPage.ts | 198 ++++++++++++++++--- mod/MonsterJournalPage/tsconfig.json | 3 +- mod/MonsterJournalPage/utilities.ts | 27 +++ 4 files changed, 201 insertions(+), 28 deletions(-) create mode 100644 mod/MonsterJournalPage/utilities.ts diff --git a/IL2CPP/type-filters.json b/IL2CPP/type-filters.json index 8b741a1..35e2d9e 100644 --- a/IL2CPP/type-filters.json +++ b/IL2CPP/type-filters.json @@ -5,6 +5,7 @@ "snow.gui.Snow", "snow.gui.fsm.smithy", "snow.gui.fsm.itembox", + "snow.gui.GuiMonsterList", "snow.envCreature" ], "type_map_filter": [ diff --git a/mod/MonsterJournalPage/MonsterJournalPage.ts b/mod/MonsterJournalPage/MonsterJournalPage.ts index 28ec06b..d45d0f8 100644 --- a/mod/MonsterJournalPage/MonsterJournalPage.ts +++ b/mod/MonsterJournalPage/MonsterJournalPage.ts @@ -1,5 +1,39 @@ -import { snow } from "IL2CPP/IL2CPP"; +import { snow, System, via, void__via_GameObject____via_wwise_RequestInfo____via_string__u32_ } from "IL2CPP/IL2CPP"; +import { cast, getObject, il_iter } from "utilities"; +function check_select_tab_pressed(): boolean { + return snow.gui.StmGuiInput.andTrg( + snow.StmInputManager.UI_INPUT.STATIC_MENU_ACT_TYPE_CL, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + false, + false + ); +} + +function check_square_pressed(): boolean { + return snow.gui.StmGuiInput.andTrg( + snow.StmInputManager.UI_INPUT.CONF_MENU_ACT_TYPE_RL, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + false, + false + ); +} function get_current_target_monsters(): snow.enemy.EnemyDef.EmTypes[] { let current_quest = snow.QuestManager.Instance.getActiveQuestData(); if (!current_quest) { @@ -7,8 +41,7 @@ function get_current_target_monsters(): snow.enemy.EnemyDef.EmTypes[] { } let data = current_quest.get_RawNormal(); - if (data) - { + if (data) { let ret = []; if (data._TargetType.Get(0) == snow.quest.QuestTargetType.AllMainEnemy) { for (let i = 0; i < data._BossEmType.get_Count(); ++i) { @@ -29,19 +62,30 @@ function get_current_target_monsters(): snow.enemy.EnemyDef.EmTypes[] { return ret; } - let mystery = current_quest.get_RandomMystery() - if (mystery) - { - let ret: number[] = [] + let mystery = current_quest.get_RandomMystery(); + if (mystery) { + let ret: number[] = []; for (let i = 0; i < mystery._HuntTargetNum; ++i) { ret.push(mystery._BossEmType.Get(i)); } return ret; - } return []; } +function get_max_group(mon_list: snow.gui.GuiMonsterList) { + let monster_info = mon_list.getCurrentMonsterInfo(); + let meat_data = snow.gui.GuiManager.Instance.monsterListParam._MeatInfoDictionary.get_Item( + monster_info._Data._EmType + ); + + let max_group = 1; + for (let obj of il_iter(meat_data._MeatContainer)) { + max_group = Math.max(obj._MeatGroupInfo.get_Count(), max_group); + } + return max_group; +} + let current_idx = 0; sdk.hook(snow.gui.GuiMonsterList.start, (args) => { @@ -51,31 +95,14 @@ sdk.hook(snow.gui.GuiMonsterList.start, (args) => { sdk.hook(snow.gui.GuiMonsterList.update, (args) => { let mon_list = sdk.to_managed_object(args[1]); - if ( - snow.gui.StmGuiInput.andTrg( - snow.StmInputManager.UI_INPUT.STATIC_MENU_ACT_TYPE_CL, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - false, - false - ) - ) { + if (check_select_tab_pressed()) { let mons = get_current_target_monsters(); if (mons.length > 0) { let mon_to_show = mons[current_idx % mons.length]; current_idx += 1; - log.info(`first monster: ${mon_to_show}`); for (let i = 0; i < mon_list._MonsterList.mSize; ++i) { if (mon_list._MonsterList.get_Item(i)._Data._EmType == mon_to_show) { - let selected_index = - mon_list._MonsterListScrollCtrl.get_selectedIndex(); + let selected_index = mon_list._MonsterListScrollCtrl.get_selectedIndex(); selected_index._HasValue = true; selected_index._Value = i; mon_list._MonsterListScrollCtrl.set_selectedIndex(selected_index); @@ -92,3 +119,120 @@ sdk.hook(snow.gui.GuiMonsterList.update, (args) => { } } }); + +{ + let self: snow.gui.GuiMonsterList; + sdk.hook( + snow.gui.GuiMonsterList.updateKeyAssign, + (args) => { + self = sdk.to_managed_object(args[1]); + }, + () => { + let assignList = snow.gui.GuiManager.Instance.get_refGuiCommonKeyAssign()._KeyAssignList; + let text = getObject(assignList.get_Items()[0], "txt_assign", via.gui.Text.T()); + let assign_text = text.get_Message(); + + if (self.getMainPageMode() == snow.gui.GuiMonsterList.PageMode.Part && get_max_group(self) > 1) { + assign_text = " Swap State " + assign_text; + } + + if (get_current_target_monsters().length > 0) { + assign_text = " Quest Monster " + assign_text; + } + text.set_Message(assign_text); + } + ); +} + +let swap_counter = 0; +sdk.hook(snow.gui.GuiMonsterList.updateEmMonsterInput, (args) => { + let self = sdk.to_managed_object(args[1]); + + if (self.getMainPageMode() != snow.gui.GuiMonsterList.PageMode.Part) { + return; + } + + if (check_square_pressed()) { + swap_counter += 1; + let monster_info = self.getCurrentMonsterInfo(); + self.updateEmMonsterPartsPage(monster_info, false); + } +}); + +{ + let text_names = [ + "txt_slash_number", + "txt_shock_number", + "txt_shot_number", + "txt_fire_number", + "txt_water_number", + "txt_thunder_number", + "txt_ice_number", + "txt_dragon_number", + ]; + + let message_id: System.Guid; + let self: snow.gui.GuiMonsterList; + let last_monster = -1; + sdk.hook( + snow.gui.GuiMonsterList.updateEmMonsterPartsPage, + (args) => { + self = sdk.to_managed_object(args[1]); + + let monster_info = self.getCurrentMonsterInfo(); + let id = monster_info._Data._EmType; + + if (id != last_monster) { + swap_counter = 0; + last_monster = id; + } + }, + () => { + let monster_info = self.getCurrentMonsterInfo(); + let meat_data = snow.gui.GuiManager.Instance.monsterListParam._MeatInfoDictionary.get_Item( + monster_info._Data._EmType + ); + + let max_group = get_max_group(self); + let current_group = swap_counter % max_group; + + // Change 'normal' message + let normal_text = getObject( + self.guiController.get_Component(), + "pnl_MonsterList_top/pnl_MonsterList/pnl_MonsterName/txt_nomal", + via.gui.Text.T() + ); + if (message_id == undefined) { + message_id = normal_text.get_MessageId(); + } + if (current_group == 0) { + normal_text.set_MessageId(message_id); + } else { + normal_text.set_MessageId(System.Guid.Empty); + normal_text.set_Message(`State ${current_group}`); + } + + let part_data = (monster_info._Data as snow.data.monsterList.BossMonsterData)._PartTableData; + let scroll_index = self._MonsterPartListlCtrl._Cursor.get_scrollIndex(); + let part_list = self._MonsterPartListlCtrl._scrL_List.get_Items(); + + // Rewrite the hitzone cells + for (let i = 0; i < part_list.get_Count() - 1; ++i) { + let current_part = part_data.get_Item(i + scroll_index); + let current_meat = meat_data._MeatContainer.get_Item(current_part._EmPart); + + for (let j = 0; j < text_names.length; ++j) { + let text_name = text_names[j]; + let gui_text = getObject(part_list.get_Item(i), text_name, via.gui.Text.T()); + if (current_group >= current_meat._MeatGroupInfo.get_Count()) { + gui_text.set_Message(" X "); + } else { + let value = meat_data.getMeatValue(current_part._EmPart, current_group, j); + let str = sdk.create_managed_string(`${value}`).add_ref(); + gui_text.set_Message(str as any); + } + } + } + } + ); +} diff --git a/mod/MonsterJournalPage/tsconfig.json b/mod/MonsterJournalPage/tsconfig.json index dd5300a..b9a9a13 100644 --- a/mod/MonsterJournalPage/tsconfig.json +++ b/mod/MonsterJournalPage/tsconfig.json @@ -13,7 +13,8 @@ "../../IL2CPP/*" ] }, - "outDir": "./dist" + "outDir": "./dist", + "target": "ES2020" }, "tstl": { "luaLibImport": "inline", diff --git a/mod/MonsterJournalPage/utilities.ts b/mod/MonsterJournalPage/utilities.ts new file mode 100644 index 0000000..c9c5a4d --- /dev/null +++ b/mod/MonsterJournalPage/utilities.ts @@ -0,0 +1,27 @@ +import { via } from "IL2CPP/IL2CPP"; + +interface NumberIterable { + get_Item(idx: number): T; + get_Count(): number; +} + +export function* il_iter(iter: NumberIterable) { + for (let i = 0; i < iter.get_Count(); ++i) { + yield iter.get_Item(i); + } +} + +export function cast(obj: REManagedObject, type: RETypeDefinition): T | undefined { + if (obj.get_type_definition().is_a(type)) { + return obj as T; + } + return undefined; +} + +export function getObject( + ctrl: via.gui.Control | via.gui.GUI, + path: string, + type: RETypeDefinition +): T | undefined { + return ctrl["getObject(System.String, System.Type)"](path, type.get_runtime_type()) as T; +} \ No newline at end of file From 629bf40f405aa5ac30b438b67288c4f3893df6f1 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Mon, 22 Aug 2022 20:48:48 +0200 Subject: [PATCH 33/39] A bit more lenient roll check --- .../GranularQuriousCrafting.ts | 62 ++++++++----------- 1 file changed, 26 insertions(+), 36 deletions(-) diff --git a/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts b/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts index d902e4e..51bd6c9 100644 --- a/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts +++ b/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts @@ -35,19 +35,18 @@ let locked_slots: boolean[]; let current_inventory_data: snow.data.EquipmentInventoryData; let buildup_count = 0; - function buildup_data() { return current_inventory_data.getArmorData().get_CustomBuildupResult(); } function remaining_cost(): number { - let cost = current_inventory_data.getArmorBaseData().get_CustomCost() + let cost = current_inventory_data.getArmorBaseData().get_CustomCost(); for (let i = 0; i < buildup_count; ++i) { if (locked_slots[i]) { cost -= buildup_data()[i].get_Cost(); } } - return cost + return cost; } function equip_is_craftable_armor(self: GuiCustomBuildup): boolean { @@ -91,11 +90,8 @@ function check_valid(armor: snow.data.ArmorData, buildups: System.Array.Generic< let budget = base_data.get_CustomCost(); for (let i = 0; i < buildups.get_Count(); ++i) { - let buildup = buildups[i] + let buildup = buildups[i]; budget -= buildup.get_Cost(); - if (budget < 0) { - return false; - } if (buildup.get_IsSkillSubBonus()) { let skill = buildup.get_PlSkillId(); @@ -107,6 +103,7 @@ function check_valid(armor: snow.data.ArmorData, buildups: System.Array.Generic< } } } + if (budget < 0) return false; return true; } @@ -186,9 +183,8 @@ function check_valid(armor: snow.data.ArmorData, buildups: System.Array.Generic< } } snow.gui.SnowGuiCommonUtility.reqSe(0xf4b6879b); - } - } + } ); } @@ -202,12 +198,12 @@ sdk.hook(GuiCustomBuildup.updateDetailWindowBySelectTopMenu, (args) => { return; } - let buildupSlot = buildup_data()[buildup_index] + let buildupSlot = buildup_data()[buildup_index]; self._TextDetailWindowMenu.set_Message(`Lock qurious slot`); self._TextDetailWindowExplain.set_Message( -`Currently in slot: ${custom_buildup_description(buildupSlot)} + `Currently in slot: ${custom_buildup_description(buildupSlot)} Available Budget: ${remaining_cost()}` - ); + ); return sdk.PreHookResult.SKIP_ORIGINAL; }); @@ -227,40 +223,35 @@ sdk.hook(GuiCustomBuildup.routineSelectTopMenu, (args) => { // Sending a negative cost to the rolling function gives invalid results let cost = buildup_data()[buildup_index].get_Cost(); if (locked_slots[buildup_index]) { - cost *= -1 + cost *= -1; } if (cost < remaining_cost()) { locked_slots[buildup_index] = !locked_slots[buildup_index]; } - self.updateMaterialListWindow() + self.updateMaterialListWindow(); self.updateDetailWindowBySelectTopMenu(); self.updateTopMenu(); return sdk.PreHookResult.SKIP_ORIGINAL; } }); -{ - let args; - sdk.hook(snow.data.CustomBuildupModule.getArmorMaterialData, (a) => { - args = a; - }, - (retval) => { - if (locked_slots) { - let param = sdk.to_managed_object(retval).MemberwiseClone() as snow.data.CustomBuildupArmorMaterialUserData.Param; - let addCost = 0; - for (let b of locked_slots) { - if (b) { - if (addCost == 0) addCost = 10; - addCost *= 2; - } +sdk.hook(snow.data.CustomBuildupModule.getArmorMaterialData, undefined, (retval) => { + if (locked_slots) { + let param = sdk.to_managed_object(retval); + param = param.MemberwiseClone() as typeof param; + let addCost = 0; + for (let b of locked_slots) { + if (b) { + if (addCost == 0) addCost = 10; + addCost *= 2; } - param._MaterialCategoryNum += addCost; - return sdk.to_ptr(param); } - return retval; - }); -} + param._MaterialCategoryNum += addCost; + return sdk.to_ptr(param); + } + return retval; +}); { let recurse_guard = false; @@ -278,7 +269,6 @@ sdk.hook(GuiCustomBuildup.routineSelectTopMenu, (args) => { let slotBlank = sdk.to_int64(args[3]) & 0xffff_ffff; let skillList = current_inventory_data.getArmorBaseData().get_AllSkillDataList(); // let skillList = sdk.to_managed_object(args[4]); - let new_cost = cost; let minimum_slot_count = 0; @@ -295,7 +285,7 @@ sdk.hook(GuiCustomBuildup.routineSelectTopMenu, (args) => { new_cost -= buildup.get_Cost(); // We reroll results until we have enough slots to fit locked slots in their place - minimum_slot_count = i + 1 + minimum_slot_count = i + 1; } } @@ -311,7 +301,7 @@ sdk.hook(GuiCustomBuildup.routineSelectTopMenu, (args) => { for (let i = 0; i < buildup_count; ++i) { if (locked_slots[i]) { - result[i] = buildup_data()[i] + result[i] = buildup_data()[i]; } } if (!check_valid(current_inventory_data.getArmorData(), result)) continue; From 53540c39832c015f919eff36a47f7c98b090ddc4 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Mon, 22 Aug 2022 21:59:58 +0200 Subject: [PATCH 34/39] Move utilities to separate project --- mod/MonsterJournalPage/MonsterJournalPage.ts | 2 +- mod/MonsterJournalPage/tsconfig.json | 4 +++ utils/tsconfig.json | 26 +++++++++++++++++++ .../MonsterJournalPage => utils}/utilities.ts | 0 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 utils/tsconfig.json rename {mod/MonsterJournalPage => utils}/utilities.ts (100%) diff --git a/mod/MonsterJournalPage/MonsterJournalPage.ts b/mod/MonsterJournalPage/MonsterJournalPage.ts index d45d0f8..2c34c1e 100644 --- a/mod/MonsterJournalPage/MonsterJournalPage.ts +++ b/mod/MonsterJournalPage/MonsterJournalPage.ts @@ -1,5 +1,5 @@ import { snow, System, via, void__via_GameObject____via_wwise_RequestInfo____via_string__u32_ } from "IL2CPP/IL2CPP"; -import { cast, getObject, il_iter } from "utilities"; +import { cast, getObject, il_iter } from "Utils/utilities"; function check_select_tab_pressed(): boolean { return snow.gui.StmGuiInput.andTrg( diff --git a/mod/MonsterJournalPage/tsconfig.json b/mod/MonsterJournalPage/tsconfig.json index b9a9a13..cd14d73 100644 --- a/mod/MonsterJournalPage/tsconfig.json +++ b/mod/MonsterJournalPage/tsconfig.json @@ -11,9 +11,13 @@ "paths": { "IL2CPP/*": [ "../../IL2CPP/*" + ], + "Utils/*": [ + "../../utils/dist/*" ] }, "outDir": "./dist", + "skipLibCheck": true, "target": "ES2020" }, "tstl": { diff --git a/utils/tsconfig.json b/utils/tsconfig.json new file mode 100644 index 0000000..08e59f8 --- /dev/null +++ b/utils/tsconfig.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://raw.githubusercontent.com/TypeScriptToLua/TypeScriptToLua/master/tsconfig-schema.json", + "compilerOptions": { + "lib": [ + "ESNext" + ], + "types": [ + "lua-types/5.4" + ], + "baseUrl": ".", + "outDir": "./dist", + "noImplicitAny": true, + "target": "ES2020", + "declaration": true + }, + "tstl": { + "luaLibImport": "inline", + "luaTarget": "5.3", + "measurePerformance": true, + "noImplicitGlobalVariables": true + }, + "include": [ + "./*", + "../IL2CPP/*" + ] +} \ No newline at end of file diff --git a/mod/MonsterJournalPage/utilities.ts b/utils/utilities.ts similarity index 100% rename from mod/MonsterJournalPage/utilities.ts rename to utils/utilities.ts From e4e429159149c1bbfe7fa83b59006d15739548c3 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Wed, 24 Aug 2022 18:30:02 +0200 Subject: [PATCH 35/39] Fix damage type order --- mod/MonsterJournalPage/MonsterJournalPage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/MonsterJournalPage/MonsterJournalPage.ts b/mod/MonsterJournalPage/MonsterJournalPage.ts index 2c34c1e..e4dea8f 100644 --- a/mod/MonsterJournalPage/MonsterJournalPage.ts +++ b/mod/MonsterJournalPage/MonsterJournalPage.ts @@ -166,8 +166,8 @@ sdk.hook(snow.gui.GuiMonsterList.updateEmMonsterInput, (args) => { "txt_shot_number", "txt_fire_number", "txt_water_number", - "txt_thunder_number", "txt_ice_number", + "txt_thunder_number", "txt_dragon_number", ]; From 5edf57633ca57923ab254bb7a780ea935657cdea Mon Sep 17 00:00:00 2001 From: Strackeror Date: Thu, 20 Apr 2023 20:00:13 +0200 Subject: [PATCH 36/39] Fix granular for TU5 --- .../GranularQuriousCrafting.ts | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts b/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts index 51bd6c9..1f593ce 100644 --- a/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts +++ b/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts @@ -34,6 +34,7 @@ function custom_buildup_description(buildup: snow.data.CustomBuildupResultData): let locked_slots: boolean[]; let current_inventory_data: snow.data.EquipmentInventoryData; let buildup_count = 0; +let menu_start_index = 0; function buildup_data() { return current_inventory_data.getArmorData().get_CustomBuildupResult(); @@ -58,7 +59,7 @@ function equip_is_craftable_armor(self: GuiCustomBuildup): boolean { function current_buildup_index(self: GuiCustomBuildup): number | undefined { let index = self._CursorCustomTopMenu.getIndex(); - let begin = 1; + let begin = menu_start_index; let end = begin + buildup_count; if (index >= begin && index < end) { return index - begin; @@ -128,17 +129,22 @@ function check_valid(armor: snow.data.ArmorData, buildups: System.Array.Generic< buildup_count = current_inventory_data.getArmorData().get_CustomBuildupResultNum(); - let new_count = self._ListCustomCategory.get_ItemCount() + buildup_count; + menu_start_index = self._ListCustomCategory.get_ItemCount(); + let new_count = menu_start_index + buildup_count; + + let cursor_index = 0; + if (keepCursor) { + cursor_index = self._ListCustomCategory.get_CursorIndex() + } self._ListCustomCategory["init(System.UInt32, System.UInt32, System.Int32, System.Int32)"]( new_count, new_count, - 0, - 0 + cursor_index, + cursor_index, ); self._ListCustomCategory.set_ItemCount(new_count); self._ListCustomCategory.set_ItemMax(new_count); self._CursorCustomTopMenu.updateMenuCursorParam(new_count, new_count); - self._CategoryMenuRemoveIndex += buildup_count; } ); } @@ -155,10 +161,11 @@ function check_valid(armor: snow.data.ArmorData, buildups: System.Array.Generic< if (!equip_is_craftable_armor(self)) { return retval; } - + let items = self._ListCustomCategory.get_Items(); for (let i = 0; i < buildup_count; ++i) { - let text = items[i + 1]["getObject(System.String, System.Type)"]( + let ui_elem_index = i + menu_start_index; + let text = items[ui_elem_index]["getObject(System.String, System.Type)"]( "pnl_MenuList/txt_menu", via.gui.Text.T().get_runtime_type() ) as via.gui.Text; @@ -169,7 +176,7 @@ function check_valid(armor: snow.data.ArmorData, buildups: System.Array.Generic< let description = custom_buildup_description(buildup); text.set_Message(`${description} [${buildup.get_Cost()}]`); - let panel = items[i + 1]["getObject(System.String, System.Type)"]( + let panel = items[ui_elem_index]["getObject(System.String, System.Type)"]( "pnl_MenuList/pnl_Status", via.gui.Panel.T().get_runtime_type() ) as via.gui.Panel; @@ -182,7 +189,6 @@ function check_valid(armor: snow.data.ArmorData, buildups: System.Array.Generic< panel.set_Visible(false); } } - snow.gui.SnowGuiCommonUtility.reqSe(0xf4b6879b); } } ); @@ -248,6 +254,9 @@ sdk.hook(snow.data.CustomBuildupModule.getArmorMaterialData, undefined, (retval) } } param._MaterialCategoryNum += addCost; + param._MaterialCategoryNum_Def += addCost; + param._MaterialCategoryNum_Skill += addCost; + param._MaterialCategoryNum_Slot += addCost; return sdk.to_ptr(param); } return retval; @@ -256,6 +265,8 @@ sdk.hook(snow.data.CustomBuildupModule.getArmorMaterialData, undefined, (retval) { let recurse_guard = false; + + // createResult(totalCost: number, slotBlank: number, baseSkillList: System.Collections.Generic.List.T1, isSort: boolean, buildupType: number, randomSeed: snow.data.FacilityDataManager.RandomSeedManual, ): System.Array.Generic; // 142b59920 let ret: any; sdk.hook( snow.data.ArmorCustomBuildupData.createResult, @@ -265,10 +276,10 @@ sdk.hook(snow.data.CustomBuildupModule.getArmorMaterialData, undefined, (retval) } let self = sdk.to_managed_object(args[1]); let cost = sdk.to_int64(args[2]) & 0xffff_ffff; - let slotBlank = sdk.to_int64(args[3]) & 0xffff_ffff; - let skillList = current_inventory_data.getArmorBaseData().get_AllSkillDataList(); - // let skillList = sdk.to_managed_object(args[4]); + let skillList = sdk.to_managed_object(args[4]); + let buildupType = sdk.to_int64(args[6]) & 0xff; + let seed = sdk.to_int64(args[7]) let new_cost = cost; let minimum_slot_count = 0; @@ -293,7 +304,7 @@ sdk.hook(snow.data.CustomBuildupModule.getArmorMaterialData, undefined, (retval) let result: ReturnType; do { - result = self.createResult(new_cost, slotBlank, skillList, false); + result = self.createResult(new_cost, slotBlank, skillList, false, buildupType, seed); if (result.get_Count() == 0) return; // Reroll if we don't have enough slots From d490a1c076f2fc717b4b61453efb66e425143fe9 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Mon, 19 Jun 2023 21:25:32 +0200 Subject: [PATCH 37/39] Improve granular qurious algorithm --- .../GranularQuriousCrafting.ts | 44 ++++++++++++------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts b/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts index 1f593ce..197c5bc 100644 --- a/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts +++ b/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts @@ -266,7 +266,6 @@ sdk.hook(snow.data.CustomBuildupModule.getArmorMaterialData, undefined, (retval) let recurse_guard = false; - // createResult(totalCost: number, slotBlank: number, baseSkillList: System.Collections.Generic.List.T1, isSort: boolean, buildupType: number, randomSeed: snow.data.FacilityDataManager.RandomSeedManual, ): System.Array.Generic; // 142b59920 let ret: any; sdk.hook( snow.data.ArmorCustomBuildupData.createResult, @@ -274,6 +273,8 @@ sdk.hook(snow.data.CustomBuildupModule.getArmorMaterialData, undefined, (retval) if (recurse_guard) { return; } + recurse_guard = true; + let self = sdk.to_managed_object(args[1]); let cost = sdk.to_int64(args[2]) & 0xffff_ffff; let slotBlank = sdk.to_int64(args[3]) & 0xffff_ffff; @@ -282,8 +283,9 @@ sdk.hook(snow.data.CustomBuildupModule.getArmorMaterialData, undefined, (retval) let seed = sdk.to_int64(args[7]) let new_cost = cost; - let minimum_slot_count = 0; + let locked_buildups = []; + // Reduce the slotblank and cost by the locked buildups for (let i = 0; i < buildup_count; ++i) { if (locked_slots[i]) { let buildup = buildup_data()[i]; @@ -291,36 +293,44 @@ sdk.hook(snow.data.CustomBuildupModule.getArmorMaterialData, undefined, (retval) if (buildup.get_IsSlotBonus()) { slotBlank -= buildup.get_Value(); } - - // Substract cost of the buildup new_cost -= buildup.get_Cost(); - // We reroll results until we have enough slots to fit locked slots in their place - minimum_slot_count = i + 1; + locked_buildups.push(buildup); } } - recurse_guard = true; - + let max_slot_count = 7 - locked_buildups.length; let result: ReturnType; do { + // Reroll until we can add the locked slots to the result result = self.createResult(new_cost, slotBlank, skillList, false, buildupType, seed); - if (result.get_Count() == 0) return; - // Reroll if we don't have enough slots - if (result.get_Count() < minimum_slot_count) continue; - - for (let i = 0; i < buildup_count; ++i) { - if (locked_slots[i]) { - result[i] = buildup_data()[i]; - } + if (result.get_Count() > max_slot_count) continue; + + // Create a new array of results, fill it with the locked buildups, then the new ones + let new_result = sdk.create_managed_array( + result.Get(0).get_type_definition().get_full_name(), + result.get_Count() + locked_buildups.length + ); + for (let i = 0; i < locked_buildups.length; ++i) { + new_result[i] = locked_buildups[i]; + } + for (let i = 0; i < result.get_Count(); ++i) { + new_result[i + locked_buildups.length] = result.Get(i); } + result = new_result; + // Reroll again if the final result is invalid if (!check_valid(current_inventory_data.getArmorData(), result)) continue; break; } while (true); - recurse_guard = false; + // Move the locked slot flags to the beginning, as the buildups have been moved + locked_slots = [false, false, false, false, false, false, false] + for (let i = 0; i < locked_buildups.length; ++i) { + locked_slots[i] = true; + } + recurse_guard = false; log.info("found result"); log.info(`${result.get_Count()}`); for (let i = 0; i < result.get_Count(); ++i) { From 8704e46d9736e11a86bb7a016a91390f75d5d5e4 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Tue, 20 Jun 2023 19:33:48 +0200 Subject: [PATCH 38/39] Correct behavior of locked slots when rerolling --- .../GranularQuriousCrafting.ts | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts b/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts index 197c5bc..156c108 100644 --- a/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts +++ b/mod/GranularQuriousCrafting/GranularQuriousCrafting.ts @@ -262,6 +262,23 @@ sdk.hook(snow.data.CustomBuildupModule.getArmorMaterialData, undefined, (retval) return retval; }); +// If buildups are locked in, the locked slots are now at the start, so move them there +sdk.hook(snow.data.EquipmentInventoryData.copy, (args) => { + let self = sdk.to_managed_object(args[1]) + log.info(`equipment copy self:${self} current:${current_inventory_data}`); + if (self == current_inventory_data) { + log.info(`move locked slots to beginning`) + let new_locked_slots = [] + for (let b of locked_slots) { + if (b) new_locked_slots.push(true); + } + while (new_locked_slots.length < 7) { + new_locked_slots.push(false) + } + locked_slots = new_locked_slots + } +}); + { let recurse_guard = false; @@ -324,12 +341,6 @@ sdk.hook(snow.data.CustomBuildupModule.getArmorMaterialData, undefined, (retval) break; } while (true); - // Move the locked slot flags to the beginning, as the buildups have been moved - locked_slots = [false, false, false, false, false, false, false] - for (let i = 0; i < locked_buildups.length; ++i) { - locked_slots[i] = true; - } - recurse_guard = false; log.info("found result"); log.info(`${result.get_Count()}`); From bcc5ae5456fd6db12311cb3403123883636bd060 Mon Sep 17 00:00:00 2001 From: Strackeror Date: Tue, 4 Jul 2023 13:20:25 +0200 Subject: [PATCH 39/39] Improve damage numbers --- IL2CPP/type-filters.json | 3 +- mod/DamageNumbers/DamageNumbers.ts | 88 ++++++++++++++++++++++++++++++ mod/DamageNumbers/tsconfig.json | 38 +++++++++++++ 3 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 mod/DamageNumbers/DamageNumbers.ts create mode 100644 mod/DamageNumbers/tsconfig.json diff --git a/IL2CPP/type-filters.json b/IL2CPP/type-filters.json index 35e2d9e..dd9aacb 100644 --- a/IL2CPP/type-filters.json +++ b/IL2CPP/type-filters.json @@ -6,7 +6,8 @@ "snow.gui.fsm.smithy", "snow.gui.fsm.itembox", "snow.gui.GuiMonsterList", - "snow.envCreature" + "snow.envCreature", + "snow.enemy.EnemyUtility" ], "type_map_filter": [ "snow.SnowSingleton", diff --git a/mod/DamageNumbers/DamageNumbers.ts b/mod/DamageNumbers/DamageNumbers.ts new file mode 100644 index 0000000..e12b850 --- /dev/null +++ b/mod/DamageNumbers/DamageNumbers.ts @@ -0,0 +1,88 @@ +import { snow } from "IL2CPP/IL2CPP"; + +type CalcInfo = snow.hit.EnemyCalcDamageInfo.AfterCalcInfo_DamageSide; +type DmgInfo = { + crit: snow.hit.CriticalType; + elem_dmg: number; +}; +let damageInstances: [number, DmgInfo][] = []; + +let config = { + elem: false +} + +let arg: CalcInfo | undefined; +sdk.hook( + snow.enemy.EnemyUtility.getHitUIColorType, + (args) => { + arg = sdk.to_managed_object(args[1]); + }, + (retval) => { + if (arg == null) { + return retval; + } + + let calcParam = arg._CalcParam; + damageInstances.push([ + arg.get_TotalDamage(), + { crit: arg.get_CriticalResult(), elem_dmg: arg.get_ElementDamage() }, + ]); + log.info(json.dump_string(damageInstances)); + let ownerType = calcParam.get_OwnerType(); + if (ownerType != snow.hit.DamageFlowOwnerType.Player && ownerType != snow.hit.DamageFlowOwnerType.PlayerShell) { + return retval; + } + let calcType = calcParam.get_CalcType(); + if (calcType != snow.enemy.EnemyDef.DamageCalcType.Slash && calcType != snow.enemy.EnemyDef.DamageCalcType.Strike) { + return retval; + } + const ColorType = snow.gui.GuiDamageDisp.ColorType; + if (sdk.to_int64(retval) == ColorType.Gray) { + return retval; + } + + if (calcParam.get_PhysicalMeatAdjustRate() > 0.44) { + return sdk.to_ptr(ColorType.Orange); + } else { + return sdk.to_ptr(ColorType.White); + } + } +); + +let self: snow.gui.GuiDamageDisp.NumDisp +let color_type: snow.gui.GuiDamageDisp.ColorType +sdk.hook( + snow.gui.GuiDamageDisp.NumDisp.startNumDisp, + ([, self_ptr, , , , color_type_ptr]) => { + self = sdk.to_managed_object(self_ptr); + color_type = sdk.to_int64(color_type_ptr); + }, + (retval) => { + let message = self._DamageText.get_Message(); + let text_dmg = Number(message); + let dmg_index = damageInstances.findIndex(([dmg]) => dmg == text_dmg); + if (dmg_index < 0) { + return retval; + } + + let new_message = "" + message; + let [, calc_info] = damageInstances.splice(dmg_index, 1)[0]; + if (damageInstances.length > 8) { + damageInstances = [] + } + if (calc_info.crit == snow.hit.CriticalType.Critical) { + new_message += "+"; + } + + if (config.elem) { + let elem_dmg = calc_info.elem_dmg; + if (elem_dmg > 0) { + new_message += `\n(${Math.floor(elem_dmg)})`; + } + } + + + if (new_message != message) self._DamageText.set_Message(new_message); + return retval + } +); diff --git a/mod/DamageNumbers/tsconfig.json b/mod/DamageNumbers/tsconfig.json new file mode 100644 index 0000000..cd14d73 --- /dev/null +++ b/mod/DamageNumbers/tsconfig.json @@ -0,0 +1,38 @@ +{ + "$schema": "https://raw.githubusercontent.com/TypeScriptToLua/TypeScriptToLua/master/tsconfig-schema.json", + "compilerOptions": { + "lib": [ + "ESNext" + ], + "types": [ + "lua-types/5.4" + ], + "baseUrl": ".", + "paths": { + "IL2CPP/*": [ + "../../IL2CPP/*" + ], + "Utils/*": [ + "../../utils/dist/*" + ] + }, + "outDir": "./dist", + "skipLibCheck": true, + "target": "ES2020" + }, + "tstl": { + "luaLibImport": "inline", + "luaTarget": "5.3", + "measurePerformance": true, + "noImplicitGlobalVariables": true, + "luaPlugins": [ + { + "name": "../../mod-exporter-plugin/mod-export-path.ts" + } + ] + }, + "include": [ + "./*", + "../../IL2CPP/*" + ] +} \ No newline at end of file