// OpenRCT2 Autosplitter by anna
// https://github.com/anna-is-cute/openrct2-autosplitter

state("openrct2", "v0.4.21 (ea5f02a)") {
    byte gScreenFlags : 0x105c9d5;
    ulong gScenarioCompletedCompanyValue : 0xf0b880, 0xe00;
    byte _mapChangedExpected : 0xf0b869;
}

state("openrct2", "v0.4.20 (1c1b6d4)") {
    byte gScreenFlags : 0x1021345;
    ulong gScenarioCompletedCompanyValue : 0xed0210, 0xe00;
    byte _mapChangedExpected : 0xed01e1;
}

state("openrct2", "v0.4.19.1 (455f22b)") {
    byte gScreenFlags : 0x1020345;
    ulong gScenarioCompletedCompanyValue : 0xecf210, 0xe00;
    byte _mapChangedExpected : 0xecf1e1;
}

state("openrct2", "v0.4.19 (088081d)") {
    byte gScreenFlags : 0x1020345;
    ulong gScenarioCompletedCompanyValue : 0xecf210, 0xe00;
    byte _mapChangedExpected : 0xecf1e1;
}

state("openrct2", "v0.4.18 (8c19879)") {
    byte gScreenFlags : 0x101fdf5;
    ulong gScenarioCompletedCompanyValue : 0xeb30c0, 0xe00;
    byte _mapChangedExpected : 0xeb3099;
}

state("openrct2", "v0.4.17 (60dc190)") {
    byte gScreenFlags : 0x100ada5;
    ulong gScenarioCompletedCompanyValue : 0xe9df60, 0xe00;
    byte _mapChangedExpected : 0xe9df39;
}

state("openrct2", "v0.4.16 (c1082a3)") {
    byte gScreenFlags : 0x1057f25;
    ulong gScenarioCompletedCompanyValue : 0x106fe60, 0xe00;
    byte _mapChangedExpected : 0x105d35c;
}

state("openrct2", "v0.4.15 (c7c8fad)") {
    byte gScreenFlags : 0xfbe6e5;
    ulong gScenarioCompletedCompanyValue : 0xe6d4a0, 0xe00;
    byte _mapChangedExpected : 0xe6d479;
}

state("openrct2", "v0.4.14 (18492da)") {
    byte gScreenFlags : 0x3ee9f35;
    ulong gScenarioCompletedCompanyValue : 0xdb2310;
    byte _mapChangedExpected : 0x3d98d11;
}

state("openrct2", "v0.4.13 (caacd4d)") {
    byte gScreenFlags : 0x3f3d425;
    ulong gScenarioCompletedCompanyValue : 0xe06310;
    byte _mapChangedExpected : 0x3dec1e1;
}

state("openrct2", "v0.4.12 (1b5ff88)") {
    byte gScreenFlags : 0x3f3ee78;
    ulong gScenarioCompletedCompanyValue : 0xe04360;
    byte _mapChangedExpected : 0x3dfca91;
}

state("openrct2", "v0.4.11 (18d2b5e)") {
    byte gScreenFlags : 0x3f076c8;
    ulong gScenarioCompletedCompanyValue : 0xdcd360;
    byte _mapChangedExpected : 0x3dc4f21;
}

state("openrct2", "v0.4.10 (e55d761)") {
    byte gScreenFlags : 0x3f01908;
    ulong gScenarioCompletedCompanyValue : 0xdd2338;
    byte _mapChangedExpected : 0x3dbf341;
}

state("openrct2", "v0.4.9 (a172405)") {
    byte gScreenFlags : 0x1ef9eb8;
    ulong gScenarioCompletedCompanyValue : 0xdcdeb0;
    byte _mapChangedExpected : 0x1db56e1;
}

state("openrct2", "v0.4.8 (05efdb2)") {
    byte gScreenFlags : 0xfa7588;
    ulong gScenarioCompletedCompanyValue : 0xdc9e50;
    byte _mapChangedExpected : 0xe62da1;
}

state("openrct2", "v0.4.7 (0e8d46e)") {
    byte gScreenFlags : 0xf8b418;
    ulong gScenarioCompletedCompanyValue : 0xf89798;
    byte _mapChangedExpected : 0xe47455;
}

state("openrct2", "v0.4.6 (b40b5da)") {
    byte gScreenFlags : 0xfeb338;
    ulong gScenarioCompletedCompanyValue : 0xfe96b8;
    byte _mapChangedExpected : 0xea7375;
}

state("openrct2", "v0.4.5 (76ca840)") {
    byte gScreenFlags : 0x100fb58;
    ulong gScenarioCompletedCompanyValue : 0x100ded8;
    byte _mapChangedExpected : 0xecbb95;
}

state("openrct2", "v0.4.4 (9e4918c)") {
    byte gScreenFlags : 0x10c8d38;
    ulong gScenarioCompletedCompanyValue : 0x10c70b8;
    byte _mapChangedExpected : 0xf71ab5;
}

state("openrct2", "v0.4.3 (285e0fc)") {
    byte gScreenFlags : 0xf864d0;
    ulong gScenarioCompletedCompanyValue : 0xf87b88;
    byte _mapChangedExpected : 0x4869dc5;
}

state("openrct2", "v0.4.2 (8ceea45)") {
    byte gScreenFlags : 0xed3290;
    ulong gScenarioCompletedCompanyValue : 0xed4948;
    byte _mapChangedExpected : 0x47b7743;
}

state("openrct2", "v0.4.1 (be518f4)") {
    byte gScreenFlags : 0xefc597;
    ulong gScenarioCompletedCompanyValue : 0xefdc50;
    byte _mapChangedExpected : 0x47e207d;
}

state("openrct2", "v0.4.0 (c6302a1)") {
    byte gScreenFlags : 0xdecee8;
    ulong gScenarioCompletedCompanyValue : 0xdee5a0;
    byte _mapChangedExpected : 0x46d66c0;
}

state("openrct2", "v0.3.5.1 (61c67af)") {
    byte gScreenFlags : 0xb5d903;
    ulong gScenarioCompletedCompanyValue : 0xb5f5d8;
}

state("openrct2", "v0.3.5 (b9bc8d0)") {
    byte gScreenFlags : 0xb5fff3;
    ulong gScenarioCompletedCompanyValue : 0xb61cc8;
}

state("openrct2", "v0.3.4.1 (5087e77)") {
    byte gScreenFlags : 0xba8d54;
    ulong gScenarioCompletedCompanyValue : 0xbaaa20;
}

state("openrct2", "v0.3.4 (e0daac9)") {
    byte gScreenFlags : 0xba8d44;
    ulong gScenarioCompletedCompanyValue : 0xbaaa10;
}

state("openrct2", "v0.3.3 (3f65f28)") {
    byte gScreenFlags : 0xb97c84;
    ulong gScenarioCompletedCompanyValue : 0xb9a7bc;
}

state("openrct2", "v0.3.2 (cea5fab)") {
    byte gScreenFlags : 0xb045a2;
    ulong gScenarioCompletedCompanyValue : 0xb06c6c;
}

state("openrct2", "v0.3.1 (d01dcea)") {
    byte gScreenFlags : 0xadd163;
    ulong gScenarioCompletedCompanyValue : 0xae078c;
}

state("openrct2", "v0.3.0 (135cc10)") {
    byte gScreenFlags : 0xa61773;
    ulong gScenarioCompletedCompanyValue : 0xa63f3c;
}

state("openrct2", "v0.2.6 (6c3c857)") {
    byte gScreenFlags : 0x910373;
    ulong gScenarioCompletedCompanyValue : 0xcb68bc;
}

state("openrct2", "v0.2.5 (4f6e77e)") {
    byte gScreenFlags : 0x90a363;
    ulong gScenarioCompletedCompanyValue : 0xcb06a0;
}

state("openrct2", "v0.2.4 (d645338)") {
    byte gScreenFlags : "openrct2.dll", 0xa669ef;
    ulong gScenarioCompletedCompanyValue : "openrct2.dll", 0xe0da24;
}

state("openrct2", "v0.2.3 (ac7a1eb)") {
    byte gScreenFlags : "openrct2.dll", 0xa51ff6;
    ulong gScenarioCompletedCompanyValue : "openrct2.dll", 0xc79128;
}

state("openrct2", "v0.2.2 (298c9f5)") {
    byte gScreenFlags : "openrct2.dll", 0xa0f63f;
    ulong gScenarioCompletedCompanyValue : "openrct2.dll", 0xcefdb4;
}

state("openrct2", "v0.2.1 (8ac731e)") {
    byte gScreenFlags : "openrct2.dll", 0x9d676a;
    ulong gScenarioCompletedCompanyValue : "openrct2.dll", 0xcb6204;
}

state("openrct2", "v0.2.0 (0aff800)") {
    byte gScreenFlags : "openrct2.dll", 0x9c2eae;
    ulong gScenarioCompletedCompanyValue : "openrct2.dll", 0xc92568;
}

state("openrct2", "v0.1.2 (0e7c0f7)") {
    byte gScreenFlags : "openrct2.dll", 0x9eb556;
    ulong gScenarioCompletedCompanyValue : "openrct2.dll", 0xca1e98;
}

state("openrct2", "v0.1.1 (4601265)") {
    byte gScreenFlags : "openrct2.dll", 0x8dfc53;
    ulong gScenarioCompletedCompanyValue : "openrct2.dll", 0xf3ba64;
}

state("openrct2", "v0.1.0 (6d1f732)") {
    byte gScreenFlags : "openrct2.dll", 0xf4cdc2;
    ulong gScenarioCompletedCompanyValue : "openrct2.dll", 0xf4c524;
}

init {
    var module = modules.First();
    string hash = vars.CalcModuleHash(module);
    switch (hash) {
        case "44b52976bb60831bfb351629d23cfb0d1c08db3d0aff104d0ecfb2fea63455f9":
            version = "v0.4.21 (ea5f02a)";
            vars.loadRemover = true;
            break;
        case "1531e13f8226b351b6621e6f2643565f72fc954c54dcc45aa1c51534c67f2099":
            version = "v0.4.20 (1c1b6d4)";
            vars.loadRemover = true;
            break;
        case "a51ffddce922f0aa858913d82028309af528321f545caddd6383f1cf111540af":
            version = "v0.4.19.1 (455f22b)";
            vars.loadRemover = true;
            break;
        case "62ebb64e2531821775e2fc130cfa0750b5ff13be82aab8004f4f5ce0644a3e38":
            version = "v0.4.19 (088081d)";
            vars.loadRemover = true;
            break;
        case "41b47eeb491513b72c9b733bd45e2e62ce941e131bbf5ecc25d17232b5087b4d":
            version = "v0.4.18 (8c19879)";
            vars.loadRemover = true;
            break;
        case "1553139ce355e93c39c58d81e6f79954dbb28a002579025958a5bb6bb91a767d":
            version = "v0.4.17 (60dc190)";
            vars.loadRemover = true;
            break;
        case "0d1fec4ecf12422747e3a414d76d489235354e6b90fccc13cfcc899c32d845b6":
            version = "v0.4.16 (c1082a3)";
            vars.loadRemover = true;
            break;
        case "da439d73fa37c32a9e829900dd379d91d62bffe20d4c39289f03f24146513827":
            version = "v0.4.15 (c7c8fad)";
            vars.loadRemover = true;
            break;
        case "125be8afd669438c086225313e2bdf2211c56803291c5c6814d0d51288260787":
            version = "v0.4.14 (18492da)";
            vars.loadRemover = true;
            break;
        case "47c7eaaf8af42243413edde7688ab1971e37b2a818d09b55507b1576c1766850":
            version = "v0.4.13 (caacd4d)";
            vars.loadRemover = true;
            break;
        case "6be0bbe387a0335fbe9c22fdbeb4c599c196e3054a4f10acd782d7d4a4ee78cf":
            version = "v0.4.12 (1b5ff88)";
            vars.loadRemover = true;
            break;
        case "4addc2ffa4c3f9f4b1c97fd64b051ab492f5e745ede8669efe3f75d42e1ba264":
            version = "v0.4.11 (18d2b5e)";
            vars.loadRemover = true;
            break;
        case "4953aad87925132c77a0a3373eac063fc7c78b5f698d2d73c09321621b444cbe":
            version = "v0.4.10 (e55d761)";
            vars.loadRemover = true;
            break;
        case "2eaaba053c6e75881936e8895dd3d2edd833cd668dd92c98780480f11ea07606":
            version = "v0.4.9 (a172405)";
            vars.loadRemover = true;
            break;
        case "4aeddcd439fe6f7969f3dad961221a6667397c70acc4f82cf17455aa5ceababa":
            version = "v0.4.8 (05efdb2)";
            vars.loadRemover = true;
            break;
        case "a744e9fd07942297f42431b210de9cbdc99667cc77e0b59cf245b9d8867d67f0":
            version = "v0.4.7 (0e8d46e)";
            vars.loadRemover = true;
            break;
        case "fdd7c68b753603dd64be9610667a5c13a5a520ed29b9df2438a5320f9a9bcb1e":
            version = "v0.4.6 (b40b5da)";
            vars.loadRemover = true;
            break;
        case "45ea93c9a3668db45c91c7a4ef38c1f01d3b04df4425900edaeeffb826592db0":
            version = "v0.4.5 (76ca840)";
            vars.loadRemover = true;
            break;
        case "7707d4752ea1a028dc9b526ce4da39af1b1331a47ae83624e81025156f7c4fad":
            version = "v0.4.4 (9e4918c)";
            vars.loadRemover = true;
            break;
        case "65c950460a7f15abdc5f6dfcdff7bcd2555d6882c50069dc8aea8bf032c90690":
            version = "v0.4.3 (285e0fc)";
            vars.loadRemover = true;
            break;
        case "fc7eb584c2cc82d4459367ea86123ad3245275c217ea92c932a7e05dfab9e8e0":
            version = "v0.4.2 (8ceea45)";
            vars.loadRemover = true;
            break;
        case "e4b01b45a22535995e6521857ea77bf71d0c4c5fcca2d72e8d242fdf3ea77b37":
            version = "v0.4.1 (be518f4)";
            vars.loadRemover = true;
            break;
        case "800e53b5505f97ec465c1592945a3f76db7f451658276b415adb250f6e6a2a8f":
            version = "v0.4.0 (c6302a1)";
            vars.loadRemover = true;
            break;
        case "87c62541f2f4c5d42f5415155ce8fac84d43565a6da860afe046f265cb738f0d":
            version = "v0.3.5.1 (61c67af)";
            vars.loadRemover = false;
            break;
        case "a8a80bd6de6675e112dc27d74ffbe359b3f9746000a1e7a484eae5f1424281b5":
            version = "v0.3.5 (b9bc8d0)";
            vars.loadRemover = false;
            break;
        case "19c08aca7b3b12160db173a481a72a3acf727d2cc842ece10fe5f5a59fabc8d9":
            version = "v0.3.4.1 (5087e77)";
            vars.loadRemover = false;
            break;
        case "7c4fde5f3f6a01ea0f291b921b6260b1a73bb90731b57d5a9606ac940446780c":
            version = "v0.3.4 (e0daac9)";
            vars.loadRemover = false;
            break;
        case "96f1a3cadeaf1e36ae38b0f91085d468be26b026948c4e96fbd599cba6c6b45d":
            version = "v0.3.3 (3f65f28)";
            vars.loadRemover = false;
            break;
        case "c3908f3291d5e007a9e719ead410669e1fe577759b2d5eed48e75d56c677f740":
            version = "v0.3.2 (cea5fab)";
            vars.loadRemover = false;
            break;
        case "e75d4d8f3455ba359cb0266c0ef3b49ed926c27a6ac7457bbdb1c020ccd8aabb":
            version = "v0.3.1 (d01dcea)";
            vars.loadRemover = false;
            break;
        case "960d49fa00c658886e66ec119f07668584ab768b21b10beade5d9d6a164c2a29":
            version = "v0.3.0 (135cc10)";
            vars.loadRemover = false;
            break;
        case "1fba35105b12c0292b16d9f003897aa5a5884f3412346da68919325827c92c0d":
            version = "v0.2.6 (6c3c857)";
            vars.loadRemover = false;
            break;
        case "f90120d4d1bb5595b23a71ea0bd52bc22d5105ca28201b5f47d14beab4cb9309":
            version = "v0.2.5 (4f6e77e)";
            vars.loadRemover = false;
            break;
        case "4d798b22ba0455cb1fc27565e5ffcb3912eeb655f2c5f5d41e61b6e4abdebfea":
            version = "v0.2.4 (d645338)";
            vars.loadRemover = false;
            break;
        case "20ebff6e0e6f4b8c7b9e93f7d9465e63a674c1581f78e1cee6745aac4d09c153":
            version = "v0.2.3 (ac7a1eb)";
            vars.loadRemover = false;
            break;
        case "7d0818603af935e960af602805b07a57a9235549b48880a51e858ef54f2676a7":
            version = "v0.2.2 (298c9f5)";
            vars.loadRemover = false;
            break;
        case "8811e80831182297410ef94b7e5e45f302753865609dc00439e8c0c8c42d2297":
            version = "v0.2.1 (8ac731e)";
            vars.loadRemover = false;
            break;
        case "71eba971aeee310c03106ba67f61769f01817168d3d4a68f2069dd04e75f9901":
            version = "v0.2.0 (0aff800)";
            vars.loadRemover = false;
            break;
        case "acd53a0c6d5759c93773eb8988ddb9657e9a54489329d7d16679aa8d541c715d":
            version = "v0.1.2 (0e7c0f7)";
            vars.loadRemover = false;
            break;
        case "16d3acefa040aa0c40c79a63e88f180a541ad2d8b778ca1cb6f4161138706b0a":
            version = "v0.1.1 (4601265)";
            vars.loadRemover = false;
            break;
        case "ca49efaf5aca4b57def8662131e3e2b65f7b3772e2787c24ebed266ecd323fcb":
            version = "v0.1.0 (6d1f732)";
            vars.loadRemover = false;
            break;
    }
}

startup {
    Func<ProcessModuleWow64Safe, string> CalcModuleHash = (module) => {
        var exeHashBytes = new byte[0];
        using (var sha = System.Security.Cryptography.SHA256.Create()) {
            using (var s = File.Open(module.FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
                exeHashBytes = sha.ComputeHash(s);
            }
        }
        return string.Join("", exeHashBytes.Select(x => x.ToString("x2")));
    };

    vars.CalcModuleHash = CalcModuleHash;
}

// check source for screenflags info. 0 is playing, non-zero is something else
start {
    if (current.gScreenFlags == 0 && old.gScreenFlags > 0) {
        return true;
    }
}

reset {
    if (current.gScreenFlags > 0 && old.gScreenFlags == 0) {
        return true;
    }
}

// search for MONEY32_UNDEFINED or MONEY64_UNDEFINED
split {
    var isComplete = (current.gScenarioCompletedCompanyValue & 0xFFFFFFFF) != 0x80000000 && current.gScenarioCompletedCompanyValue != 0x8000000000000000;
    var isFailed = (current.gScenarioCompletedCompanyValue & 0xFFFFFFFF) == 0x80000001 || current.gScenarioCompletedCompanyValue == 0x8000000000000001;
    var wasIncomplete = (old.gScenarioCompletedCompanyValue & 0xFFFFFFFF) == 0x80000000 || old.gScenarioCompletedCompanyValue == 0x8000000000000000;
    if (current.gScreenFlags == 0 && isComplete && !isFailed && wasIncomplete) {
        return true;
    }
}

isLoading {
    return vars.loadRemover && current._mapChangedExpected == 1;
}