state("Morrowind", "v1.0") { string50 cell : 0x3AEA88, 0xB540, 0x10, 0; string50 region : 0x3AEA88, 0xB540, 0x8C, 0x30; // float playerX : 0x3AEA88, 0, 0xAC40, 0x38; // float playerY : 0x3AEA88, 0, 0xAC40, 0x3C; // float playerZ : 0x3AEA88, 0, 0xAC40, 0x40; bool playerControlsDisabled : 0x3AEA84, 0x5C, 0x24, 0, 0x5A0; bool loadingScreenVisible : 0x3BBCE0; bool extraLoadingCheck : 0x3B0704; float fadeInTime : 0x3AEA84, 0x348, 0x4; // Not 100% certain what this address correlates to but the behavior is as follows // 255 when loading or walking around (no menus). 0 When dialog/menu are open... UNLESS mousing over a dialog border, then 1. byte dialogIcon : 0x3AEA84, 0x50, 0x14; float gameTime : 0x3AE9B0; } state("Morrowind", "goty") { string50 cell : 0x3C67E0, 0xB540, 0x10, 0; string50 region : 0x3C67E0, 0xB540, 0x90, 0x30; // float playerX : 0x3AEA88, 0, 0xAC40, 0x38; // float playerY : 0x3AEA88, 0, 0xAC40, 0x3C; // float playerZ : 0x3AEA88, 0, 0xAC40, 0x40; bool playerControlsDisabled : 0x003C67DC, 0x5C, 0x24, 0x0, 0x5B0; bool loadingScreenVisible : 0x3D4294; bool extraLoadingCheck : 0x3C85B8; float fadeInTime : 0x3C67DC, 0x354, 0x4; // Not 100% certain what this address correlates to but the behavior is as follows // 255 when loading or walking around (no menus). 0 When dialog/menu are open... UNLESS mousing over a dialog border, then 1. byte dialogIcon : 0x3C67DC, 0x50, 0x14; float gameTime : 0x3C6708; } init { print("[Morrowind NoLoads] Module size: " + modules.First().ModuleMemorySize); if (modules.First().ModuleMemorySize == 4431872) { version = "goty"; } else if (modules.First().ModuleMemorySize == 3981312) { version = "v1.0"; } } startup { vars.prevPhase = null; vars.isLoading = false; vars.wasLoading = false; vars.loadingChecks = 0; vars.doStart = false; vars.doSplit = false; vars.doReset = false; vars.balmoraHasSplit = false; vars.potionShopVisited = false; settings.Add("any", false, "Any%"); settings.Add("any_guard", false, "Leave Ship", "any"); settings.Add("any_redguard", false, "Pick Redguard", "any"); settings.Add("any_steal", false, "Steal Platter", "any"); settings.Add("any_ring", false, "Give Ring", "any"); settings.Add("any_trade", false, "Trade", "any"); settings.Add("any_rip", false, "Catch ", "any"); settings.Add("any_walk", false, "Walk", "any"); settings.Add("any_witch", false, "Buy Potions", "any"); settings.Add("any_fly", false, "Fly", "any"); settings.Add("any_dagger", false, "Get Keening", "any"); settings.Add("any_fast", false, "Go Fast", "any"); settings.Add("any_hammer", false, "Get Sunder", "any"); settings.Add("any_noclip", false, "Noclip", "any"); settings.Add("any_end", false, "End", "any"); settings.Add("amq", true, "All Main Quests"); settings.Add("amq_seyda_neen", true, "Seyda Neen", "amq"); settings.Add("amq_red_mountain", true, "Red Mountain", "amq"); settings.Add("amq_astral_burial", true, "Astral Burial", "amq"); settings.Add("amq_potion_shop", true, "Potion Shop", "amq"); settings.Add("amq_balmora", true, "Balmora", "amq"); settings.Add("amq_vivec", true, "Vivec", "amq"); settings.Add("amq_ald_ruhn", true, "Ald-ruhn", "amq"); settings.Add("amq_sul_matuul", true, "Sul-Matuul", "amq"); settings.Add("amq_path_of_the_incarnate", true, "Path of the Incarnate", "amq"); settings.Add("amq_ahemmusa", true, "Ahemmusa", "amq"); settings.Add("amq_redoran_councillors", true, "Redoran Councillors", "amq"); settings.Add("amq_sixth_house_base", true, "Sixth House Base", "amq"); settings.Add("amq_erabenimsun", true, "Erabenimsun", "amq"); settings.Add("amq_corpus_cure", true, "Corpus Cure", "amq"); settings.Add("amq_zainab", true, "Zainab", "amq"); settings.Add("amq_lost_prophecies", true, "Lost Prophecies", "amq"); settings.Add("amq_redoran", true, "Redoran", "amq"); settings.Add("amq_hlaalu", true, "Hlaalu", "amq"); settings.Add("amq_hortator_and_nerevarine", true, "Hortator and Nerevarine", "amq"); settings.Add("amq_dagoth_ur", true, "Dagoth Ur", "amq"); } exit { timer.IsGameTimePaused = true; } update { current.cell = current.cell != null && current.cell.Length > 0 && current.region != null && current.region.Length > 0 ? String.Join(" - ", current.cell, current.region) : (current.cell != null && current.cell.Length > 0 ? current.cell : current.region); if (timer.CurrentPhase == TimerPhase.Running && vars.prevPhase == TimerPhase.NotRunning) { // reset split trackers on start vars.balmoraHasSplit = false; vars.potionShopVisited = false; } vars.prevPhase = timer.CurrentPhase; // Always trust the original loading screen visible // Extra loading check added as loadingScreenVisible doesn't handle all cases // Extra loading check has a few edge cases (something to do with dialog immediately after journal entry). Check if we still fading in/out vars.isLoading = current.loadingScreenVisible || (current.extraLoadingCheck && current.dialogIcon > 1 && current.fadeInTime > 0.0); vars.wasLoading = old.loadingScreenVisible || (old.extraLoadingCheck && old.dialogIcon > 1 && old.fadeInTime > 0.0); if (vars.isLoading) { if (!vars.wasLoading) { print("[Morrowind NoLoads] Started Loading. " + DateTime.Now + "("+ DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond + ") Variables: current.loadingScreenVisible " +current.loadingScreenVisible+ " current.extraLoadingCheck " +current.extraLoadingCheck+ " current.dialogIcon " +current.dialogIcon + " last gametime " + old.gameTime + " current gameTime " + current.gameTime); } vars.loadingChecks++; } else { if (vars.wasLoading) { print("[Morrowind NoLoads] Finished Loading after " + vars.loadingChecks + " checks. " + DateTime.Now + "("+ DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond + ") Variables: current.loadingScreenVisible " +current.loadingScreenVisible+ " current.extraLoadingCheck " +current.extraLoadingCheck+ " current.dialogIcon " +current.dialogIcon + " last gametime " + old.gameTime + " current gameTime " + current.gameTime); vars.loadingChecks = 0; } } vars.doStart = false; vars.doSplit = false; vars.doReset = false; if (current.playerControlsDisabled != old.playerControlsDisabled) { if (current.playerControlsDisabled) { print("[Morrowind NoLoads] player controls disabled"); if (current.cell == "Dagoth Ur, Facility Cavern" && (settings["any_end"] || settings["amq_dagoth_ur"])) { // split 20 Dagoth Ur vars.doSplit = true; } } else { print("[Morrowind NoLoads] player controls enabled"); if (!current.loadingScreenVisible && current.cell == "Imperial Prison Ship") { // start vars.doStart = true; } } } if (current.cell != old.cell) { print(String.Format("[Morrowind NoLoads] cell changed from '{0}' to '{1}'", old.cell, current.cell)); // Any% if (settings["any"]) { if (settings["any_guard"] && old.cell == "Imperial Prison Ship") { vars.doSplit = true; } else if (settings["any_redguard"] && current.cell == "Seyda Neen, Census and Excise Office") { vars.doSplit = true; } else if (settings["any_steal"] && old.cell == "Seyda Neen, Census and Excise Office") { vars.doSplit = true; } else if (settings["any_ring"] && current.cell == "Seyda Neen, Arrille's Tradehouse") { vars.doSplit = true; } else if (settings["any_trade"] && old.cell == "Seyda Neen, Arrille's Tradehouse") { vars.doSplit = true; } else if (settings["any_rip"] && old.cell == "Bitter Coast Region" && current.cell == "Balmora - West Gash Region") { vars.doSplit = true; } else if (settings["any_walk"] && current.cell == "Balmora, Nalcarya of White Haven: Fine Alchemist") { vars.doSplit = true; } else if (settings["any_witch"] && old.cell == "Balmora, Nalcarya of White Haven: Fine Alchemist") { vars.doSplit = true; } else if (settings["any_fly"] && old.cell == "Odrosal - Red Mountain Region" && current.cell == "Odrosal, Dwemer Training Academy") { vars.doSplit = true; } else if (settings["any_dagger"] && old.cell == "Odrosal, Dwemer Training Academy" && current.cell != "Odrosal, Tower") { vars.doSplit = true; } else if (settings["any_fast"] && current.cell == "Vemynal, Outer Fortress") { vars.doSplit = true; } else if (settings["any_hammer"] && old.cell == "Vemynal, Hall of Torque") { vars.doSplit = true; } else if (settings["any_noclip"] && current.cell == "Akulakhan's Chamber") { vars.doSplit = true; } } if (settings["amq"]) { if (settings["amq_seyda_neen"] && old.cell == "Bitter Coast Region" && current.cell == "Balmora - West Gash Region") { // split 01 Seyda Neen vars.doSplit = true; } else if (settings["amq_red_mountain"] && old.cell == "Vemynal, Outer Fortress" && current.cell != "Vemynal, Hall of Torque") { // split 02 Red Mountain vars.doSplit = true; } else if (settings["amq_astral_burial"] && old.cell == "Urshilaku, Juno Burial") { // split 03 Astral Burial vars.doSplit = true; } else if (settings["amq_potion_shop"] && old.cell == "Balmora, Nalcarya of White Haven: Fine Alchemist" && vars.potionShopVisited) { // split 04 Potion Shop vars.doSplit = true; } else if (settings["amq_balmora"] && old.cell == "Balmora - West Gash Region" && current.cell == "Vivec - Ascadian Isles Region" && !vars.balmoraHasSplit) { // split 05 Balmora vars.doSplit = true; // split make sure this doesn't double split vars.balmoraHasSplit = true; } else if (settings["amq_vivec"] && old.cell == "Vivec, Library of Vivec") { // split 06 Vivec vars.doSplit = true; } else if (settings["amq_ald_ruhn"] && old.cell == "Ald-ruhn - Ashlands Region" && current.cell == "Khuul - West Gash Region") { // split 07 Ald-ruhn vars.doSplit = true; } else if (settings["amq_sul_matuul"] && old.cell == "Urshilaku Camp, Wise Woman's Yurt") { // split 08 Sul-Matuul vars.doSplit = true; } else if (settings["amq_path_of_the_incarnate"] && old.cell == "Cavern of the Incarnate") { // split 09 Path of the Incarnate vars.doSplit = true; } else if (settings["amq_ahemmusa"] && old.cell == "Urshilaku Camp, Ashkhan's Yurt" && current.cell == "Ald-ruhn - Ashlands Region") { // split 10 Ahemmusa vars.doSplit = true; } else if (settings["amq_redoran_councillors"] && old.cell == "Ald-ruhn - Ashlands Region" && current.cell == "Balmora - West Gash Region") { // split 11 Redoran Councillors vars.doSplit = true; } else if (settings["amq_sixth_house_base"] && old.cell == "Vivec - Ascadian Isles Region" && current.cell == "Molag Mar - Molag Amur Region") { // split 12 Sixth House Base vars.doSplit = true; } else if (settings["amq_erabenimsun"] && old.cell == "Erabenimsun Camp, Han-Ammu's Yurt") { // split 13 Erabenimsun vars.doSplit = true; } else if (settings["amq_corpus_cure"] && old.cell == "Tower of Tel Fyr, Hall of Fyr" && current.cell == "Wolverine Hall - Azura's Coast Region") { // split 14 Corpus Cure vars.doSplit = true; } else if (settings["amq_zainab"] && old.cell == "Zainab Camp, Ashkhan's Yurt" && current.cell == "Vivec - Ascadian Isles Region") { // split 15 Zainab vars.doSplit = true; } else if (settings["amq_lost_prophecies"] && old.cell == "Holamayan Monastery" && current.cell == "Vivec - Ascadian Isles Region") { // split 16 Lost Prophecies vars.doSplit = true; } else if (settings["amq_redoran"] && old.cell == "Ald-ruhn, Sarethi Manor" && current.cell == "Vivec - Ascadian Isles Region") { // split 17 Redoran vars.doSplit = true; } else if (settings["amq_hlaalu"] && old.cell == "Vivec, Curio Manor" && current.cell == "Vivec, Temple - Ascadian Isles Region") { // split 18 Hlaalu vars.doSplit = true; } else if (settings["amq_hortator_and_nerevarine"] && old.cell == "Vivec, Palace of Vivec" && current.cell == "Vivec - Ascadian Isles Region") { // split 19 Hortator and Nerevarine vars.doSplit = true; } } if (old.cell == "Balmora, Nalcarya of White Haven: Fine Alchemist") { // enable potion shop split vars.potionShopVisited = true; } } if (current.loadingScreenVisible != old.loadingScreenVisible) { if (current.loadingScreenVisible) { print("[Morrowind NoLoads] Loading screen started"); } else { print("[Morrowind NoLoads] Loading screen ended"); if (current.cell == "Imperial Prison Ship") { // load finish in prison ship means reset vars.doReset = true; } } } // if (old.playerX != current.playerX || old.playerY != current.playerY || old.playerZ != current.playerZ) // print(String.Format("[Morrowind NoLoads] x,y,z changed from {0},{1},{2} to {3},{4},{5}", old.playerX, old.playerY, old.playerZ, current.playerX, current.playerY, current.playerZ)); } start { return vars.doStart; } split { return vars.doSplit; } reset { return vars.doReset; } isLoading { return vars.isLoading; } // Any% // 01 from 'Imperial Prison Ship' to 'Ashlands Region' // or 'Ashlands Region' to 'Seyda Neen - Bitter Coast Region' // 02 from 'Seyda Neen - Bitter Coast Region' to 'Seyda Neen, Census and Excise Office' // 03 from 'Seyda Neen, Census and Excise Office' to 'Ashlands Region' // or 'Ashlands Region' to 'Seyda Neen - Bitter Coast Region' // 04 from 'Seyda Neen - Bitter Coast Region' to 'Seyda Neen, Arrille's Tradehouse' // 05 from 'Seyda Neen, Arrille's Tradehouse' to 'West Gash Region' // 06 from 'Bitter Coast Region' to 'Balmora - West Gash Region' // 07 from 'Balmora - West Gash Region' to 'Balmora, Nalcarya of White Haven: Fine Alchemist' // 08 from 'Balmora, Nalcarya of White Haven: Fine Alchemist' to 'Balmora - West Gash Region' // 09 from 'Odrosal - Red Mountain Region' to 'Odrosal, Dwemer Training Academy' // 10 from 'Odrosal, Dwemer Training Academy' to 'Ashlands Region' // or 'Ashlands Region' to 'Odrosal - Red Mountain Region' // 11 from 'Vemynal - Red Mountain Region' to 'Vemynal, Outer Fortress' // 12 from 'Vemynal, Hall of Torque' to 'Dagoth Ur - Red Mountain Region' // 13 from 'Dagoth Ur, Facility Cavern' to 'Akulakhan's Chamber' // 14 last split // AMQ // 01 from 'Bitter Coast Region' to 'Balmora - West Gash Region' // 02 from 'Vemynal, Outer Fortress' to 'Ashlands Region' // or 'Ashlands Region' to 'Vemynal - Red Mountain Region' // 03 from 'Urshilaku, Juno Burial' to 'Balmora, Nalcarya of White Haven: Fine Alchemist' // 04 from 'Balmora, Milie Hastien: Fine Clothier' to 'West Gash Region' // or 'West Gash Region' to 'Balmora - West Gash Region' // 05 from 'Balmora - West Gash Region' to 'Vivec - Ascadian Isles Region' // 06 from 'Vivec, Library of Vivec' to 'Balmora, Caius Cosades' House' // 07 from 'Ald-ruhn - Ashlands Region' to 'Khuul - West Gash Region' // 08 from 'Urshilaku Camp, Wise Woman's Yurt' to 'West Gash Region' // or 'West Gash Region' to 'Urshilaku Camp - Ashlands Region' // 09 from 'Cavern of the Incarnate' to 'Ashlands Region' // 10 from 'Urshilaku Camp, Ashkhan's Yurt' to 'Ald-ruhn - Ashlands Region' // 11 from 'Ald-ruhn - Ashlands Region' to 'Balmora - West Gash Region' // 12 from 'Vivec - Ascadian Isles Region' to 'Molag Mar - Molag Amur Region' // 13 from 'Erabenimsun Camp, Han-Ammu's Yurt' to 'Ashlands Region' // or 'Ashlands Region' to 'Erabenimsun Camp - Molag Amur Region' // 14 from 'Tower of Tel Fyr, Hall of Fyr' to 'Wolverine Hall - Azura's Coast Region' // 15 from 'Zainab Camp, Ashkhan's Yurt' to 'Vivec - Ascadian Isles Region' // 16 from 'Holamayan Monastery' to 'Vivec - Ascadian Isles Region' // 17 from 'Ald-ruhn, Sarethi Manor' to 'Vivec - Ascadian Isles Region' // 18 from 'Vivec, Curio Manor' to 'Vivec, Temple - Ascadian Isles Region' // 19 from 'Vivec, Palace of Vivec' to 'Vivec - Ascadian Isles Region' // 20 last split