/* ** ENDER MAGNOLIA: Bloom in the Mist by Trex ** https://discord.gg/wWQUzB36dx */ state("EnderMagnoliaSteamEA-Win64-Shipping", "Steam Early Access, 0.5.0") { //int GObjects : 0x7FF6DC9F77A0; } state("EnderMagnoliaSteamEA-Win64-Shipping", "Steam Early Access, 0.5.1") { //int GObjects : 0x7FF6DC9F77A0; // GUObjectArray = 7FF6671C77F0 // FNamePool = 7FF667121440 } state("EnderMagnoliaSteam-Win64-Shipping", "Steam 1.0.2") { //int GEngine : 0x7EEF600; } state("EnderMagnoliaSteam-Win64-Shipping", "Steam 1.0.3") { // GEngine : 0x07EF2780 long world: 0x07EF2780, 0xA80, 0x78; //int GEngine->GameViewport->World->PersistentLevel->LevelBuildDataId long LevelBuildDataId: 0x07EF2780, 0xA80, 0x78, 0x30, 0x210; //int GEngine->GameViewport->World->GameMode->ZoneSystemComponent->ActiveZoneLevelStreaming->Name int LevelName: 0x07EF2780, 0xA80, 0x78, 0x158, 0x4B0, 0xF8, 0x38; //int GEngine->GameViewport->World->GameMode->ZoneSystemComponent->ActiveZoneLevelStreaming->Name int PackageNameToLoad: 0x07EF2780, 0xA80, 0x78, 0x158, 0x4B0, 0xF8, 0x54; //int GEngine->GameViewport->World->GameMode->ZoneSystemComponent->switchingZone bool switchingZone: 0x07EF2780, 0xA80, 0x78, 0x158, 0x4B0, 0x101; // GEngine->GameInstance->SybSystems->WorldLoader->IsLoading bool isLoading: 0x07EF2780, 0x10A8, 0x108, 0x128, 0xA8; // GEngine->GameInstance->SybSystems->Save->SaveBackupNumber int SaveBackup: 0x07EF2780, 0x10A8, 0x108, 0x50, 0x7C; int RespawnRestPointID: 0x07EF2780, 0x10A8, 0x38, 0, 0x30, 0x9D8; double timeSinceStartup: 0x07EF2780, 0xA80, 0x78, 0x6C0; } state("EnderMagnoliaSteam-Win64-Shipping", "Steam 1.0.4") { // GEngine : 07EF4980 // GEngine->GameViewport->World long world: 0x07EF4980, 0xA80, 0x78; // GEngine->GameViewport->World->PersistentLevel->LevelBuildDataId long LevelBuildDataId: 0x07EF4980, 0xA80, 0x78, 0x30, 0x210; // GEngine->GameViewport->World->GameMode->ZoneSystemComponent->ActiveZoneLevelStreaming->Name int LevelName: 0x07EF4980, 0xA80, 0x78, 0x158, 0x4B0, 0xF8, 0x38; // GEngine->GameViewport->World->GameMode->ZoneSystemComponent->ActiveZoneLevelStreaming->Name int PackageNameToLoad: 0x07EF4980, 0xA80, 0x78, 0x158, 0x4B0, 0xF8, 0x54; // GEngine->GameViewport->World->GameMode->ZoneSystemComponent->switchingZone bool switchingZone: 0x07EF4980, 0xA80, 0x78, 0x158, 0x4B0, 0x101; // GEngine->GameInstance->LocalPlayer->0->PlayerController->PlayerCameraManager->ViewTargetActor->EnemyPawnTargets->Count int EnemyTargetsCount: 0x07EF4980, 0x10A8, 0x38, 0x0, 0x30, 0x348, 0x320, 0xA40; // GEngine->GameInstance->LocalPlayer->0->PlayerController->PlayerCameraManager->ViewTargetActor->EnemyPawnTargets->0 int EnemyTargetObjectIndex: 0x07EF4980, 0x10A8, 0x38, 0x0, 0x30, 0x348, 0x320, 0xA38, 0x0; // GEngine->GameInstance->SybSystems->WorldLoader->IsLoading bool isLoading: 0x07EF4980, 0x10A8, 0x108, 0x128, 0xA8; // GEngine->GameInstance->SybSystems->Save->SaveBackupNumber int SaveBackup: 0x07EF4980, 0x10A8, 0x108, 0x50, 0x7C; int RespawnRestPointID: 0x07EF4980, 0x10A8, 0x38, 0, 0x30, 0x9D8; double timeSinceStartup: 0x07EF4980, 0xA80, 0x78, 0x6C0; // GEngine->GameInstance->LocalPlayer->0->PlayerController->InventoryComponent->xx long AptitudeInventory: 0x07EF4980, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x178; long KeyInventory: 0x07EF4980, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x1C8; long QuestInventory: 0x07EF4980, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x1D0; long SpiritInventory: 0x07EF4980, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x180; long EquipmentInventory: 0x07EF4980, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x190; long PassiveInventory: 0x07EF4980, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x1A8; long AssistInventory: 0x07EF4980, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x0198; long MaterialInventory: 0x07EF4980, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x01B0; long StatsInventory: 0x07EF4980, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x01A0; // GEngine->GameInstance->LocalPlayer->0->PlayerController->PlayerUI->WBP_Minimap->CurrentWidgetArea->CachedMapIcons long CachedIcons: 0x07EF4980, 0x10A8, 0x38, 0x0, 0x30, 0x9C8, 0x468, 0x4E0, 0x498; int CachedIconsCount: 0x07EF4980, 0x10A8, 0x38, 0x0, 0x30, 0x9C8, 0x468, 0x4E0, 0x4A0; } state("EnderMagnoliaSteam-Win64-Shipping", "Steam 1.1.0") { // GEngine : 0x80C5F00 // GEngine->GameViewport->World long world: 0x80C5F00, 0xA80, 0x78; // GEngine->GameViewport->World->PersistentLevel->LevelBuildDataId long LevelBuildDataId: 0x80C5F00, 0xA80, 0x78, 0x30, 0x210; // GEngine->GameViewport->World->GameMode->ZoneSystemComponent->ActiveZoneLevelStreaming->Name int LevelName: 0x80C5F00, 0xA80, 0x78, 0x158, 0x4B0, 0xF8, 0x38; // GEngine->GameViewport->World->GameMode->ZoneSystemComponent->ActiveZoneLevelStreaming->Name int PackageNameToLoad: 0x80C5F00, 0xA80, 0x78, 0x158, 0x4B0, 0xF8, 0x54; // GEngine->GameViewport->World->GameMode->ZoneSystemComponent->switchingZone bool switchingZone: 0x80C5F00, 0xA80, 0x78, 0x158, 0x4B0, 0x101; // GEngine->GameInstance->LocalPlayer->0->PlayerController->PlayerCameraManager->ViewTargetActor->EnemyPawnTargets->Count int EnemyTargetsCount: 0x80C5F00, 0x10A8, 0x38, 0x0, 0x30, 0x348, 0x320, 0xA40; // GEngine->GameInstance->LocalPlayer->0->PlayerController->PlayerCameraManager->ViewTargetActor->EnemyPawnTargets->0 int EnemyTargetObjectIndex: 0x80C5F00, 0x10A8, 0x38, 0x0, 0x30, 0x348, 0x320, 0xA38, 0x0; // GEngine->GameInstance->SybSystems->WorldLoader->IsLoading bool isLoading: 0x80C5F00, 0x10A8, 0x108, 0x128, 0xA8; // GEngine->GameInstance->SybSystems->Save->SaveBackupNumber int SaveBackup: 0x80C5F00, 0x10A8, 0x108, 0x50, 0x7C; int RespawnRestPointID: 0x80C5F00, 0x10A8, 0x38, 0, 0x30, 0x9D8; double timeSinceStartup: 0x80C5F00, 0xA80, 0x78, 0x6C0; // GEngine->GameInstance->LocalPlayer->0->PlayerController->InventoryComponent->xx long AptitudeInventory: 0x80C5F00, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x178; long KeyInventory: 0x80C5F00, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x1C8; long QuestInventory: 0x80C5F00, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x1D0; long SpiritInventory: 0x80C5F00, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x180; long EquipmentInventory: 0x80C5F00, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x190; long PassiveInventory: 0x80C5F00, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x1A8; long AssistInventory: 0x80C5F00, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x0198; long MaterialInventory: 0x80C5F00, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x01B0; long StatsInventory: 0x80C5F00, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x01A0; // GEngine->GameInstance->LocalPlayer->0->PlayerController->PlayerUI->WBP_Minimap->CurrentWidgetArea->CachedMapIcons long CachedIcons: 0x80C5F00, 0x10A8, 0x38, 0x0, 0x30, 0x9C8, 0x468, 0x4E0, 0x498; int CachedIconsCount: 0x80C5F00, 0x10A8, 0x38, 0x0, 0x30, 0x9C8, 0x468, 0x4E0, 0x4A0; } state("EnderMagnoliaSteam-Win64-Shipping", "Steam 1.1.1") { // GEngine : 0x80C8F80 // GEngine->GameViewport->World long world: 0x80C8F80, 0xA80, 0x78; // GEngine->GameViewport->World->PersistentLevel->LevelBuildDataId long LevelBuildDataId: 0x80C8F80, 0xA80, 0x78, 0x30, 0x210; // GEngine->GameViewport->World->GameMode->ZoneSystemComponent->ActiveZoneLevelStreaming->Name int LevelName: 0x80C8F80, 0xA80, 0x78, 0x158, 0x4B0, 0xF8, 0x38; // GEngine->GameViewport->World->GameMode->ZoneSystemComponent->ActiveZoneLevelStreaming->Name int PackageNameToLoad: 0x80C8F80, 0xA80, 0x78, 0x158, 0x4B0, 0xF8, 0x54; // GEngine->GameViewport->World->GameMode->ZoneSystemComponent->switchingZone bool switchingZone: 0x80C8F80, 0xA80, 0x78, 0x158, 0x4B0, 0x101; // GEngine->GameInstance->LocalPlayer->0->PlayerController->PlayerCameraManager->ViewTargetActor->EnemyPawnTargets->Count int EnemyTargetsCount: 0x80C8F80, 0x10A8, 0x38, 0x0, 0x30, 0x348, 0x320, 0xA40; // GEngine->GameInstance->LocalPlayer->0->PlayerController->PlayerCameraManager->ViewTargetActor->EnemyPawnTargets->0 int EnemyTargetObjectIndex: 0x80C8F80, 0x10A8, 0x38, 0x0, 0x30, 0x348, 0x320, 0xA38, 0x0; // GEngine->GameInstance->SybSystems->WorldLoader->IsLoading bool isLoading: 0x80C8F80, 0x10A8, 0x108, 0x128, 0xA8; // GEngine->GameInstance->SybSystems->Save->SaveBackupNumber int SaveBackup: 0x80C8F80, 0x10A8, 0x108, 0x50, 0x7C; int RespawnRestPointID: 0x80C8F80, 0x10A8, 0x38, 0, 0x30, 0x9D8; double timeSinceStartup: 0x80C8F80, 0xA80, 0x78, 0x6C0; // GEngine->GameInstance->LocalPlayer->0->PlayerController->InventoryComponent->xx long AptitudeInventory: 0x80C8F80, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x178; long KeyInventory: 0x80C8F80, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x1C8; long QuestInventory: 0x80C8F80, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x1D0; long SpiritInventory: 0x80C8F80, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x180; long EquipmentInventory: 0x80C8F80, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x190; long PassiveInventory: 0x80C8F80, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x1A8; long AssistInventory: 0x80C8F80, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x0198; long MaterialInventory: 0x80C8F80, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x01B0; long StatsInventory: 0x80C8F80, 0x10A8, 0x38, 0x0, 0x30, 0x978, 0x01A0; // GEngine->GameInstance->LocalPlayer->0->PlayerController->PlayerUI->WBP_Minimap->CurrentWidgetArea->CachedMapIcons long CachedIcons: 0x80C8F80, 0x10A8, 0x38, 0x0, 0x30, 0x9C8, 0x468, 0x4E0, 0x498; int CachedIconsCount: 0x80C8F80, 0x10A8, 0x38, 0x0, 0x30, 0x9C8, 0x468, 0x4E0, 0x4A0; } startup { // LevelBuildDataId vars.InGameLevelID = 0x4D8E43C149362583; vars.TitleLevelID = 0x4706DC27818385BD; // locals vars.lastLevel = 0x0; vars.aptitudes = new Dictionary<string, string> { //{ "crouch", "Healing Ward"}, //{ "dodge", "Aerial Jump"}, //{ "dodge_weak", "Fast Travel"}, //{ "jump", "Garm's Iron Stake"}, //{ "dash", "Hati's Charge"}, { "heal", "Healing Ward"}, { "double_jump", "Aerial Jump"}, { "fast_travel", "Fast Travel"}, { "pile_attack", "Garm's Iron Stake"}, { "dash_charge", "Hati's Charge"}, { "wall_grab", "Lar's Grip"}, { "dive", "Dive"}, { "hook", "Motley's Magic Strands"}, { "sp", "Attuner Arts"}, { "dash_charge_underwater", "Motley's Torrent"}, { "high_jump", "Garm's Ascent"}, { "wall_charge", "Lar's Swift Flight"}, }; vars.keys = new Dictionary<string, string> { { "key_ruins_tuto", "Subterranean Testing Site Key"}, { "key_lower", "Lower Stratum Key"}, { "key_higher_a", "Frost Lord's Mark"}, { "key_owner", "Grand Sorcerer's Key"}, { "key_higher_b", "Milius Lord's Mark"}, }; vars.quests = new Dictionary<string, string> { { "quest_artifact", "Mutated Mineral"}, { "quest_stone", "Frost Vestige"}, { "quest_bird", "Avian Remains"}, { "quest_perfume", "Black Perfume"}, { "quest_eye", "Blighted Pupil"}, { "quest_lithograph", "Stele of the Land of Origin"}, { "quest_board", "Milius Resident Records"}, { "quest_amulet", "Faintly Glowing Aegis Curio"}, }; vars.spirits = new Dictionary<string, string> { { "s5000_reaper", "Nola"}, { "s5010_lancer", "Reibolg"}, { "s5110_gunman", "Yolvan"}, { "s5070_witch", "Luiseach"}, { "s5030_rogue", "Lito"}, { "s5050_ronin", "No.7"}, { "s5060_beast", "Shackled Beast"}, { "s5040_maiden", "Lorna"}, { "s5090_owl", "Muninn"}, { "s5080_hawk", "Huginn"}, }; // bracelets vars.equipments_1 = new Dictionary<string, string> { {"armor_021", "Celestial Bangle"}, {"armor_020", "Ancient's Fury"}, {"armor_019", "Upper Stratum Bangle"}, {"armor_018", "Aster Bangle"}, {"armor_017", "Sol Bangle"}, {"armor_016", "Lunar Bangle"}, {"armor_015", "Declan's Binds"}, {"armor_014", "Abelia's Bracelet"}, {"armor_013", "Spire Bangle"}, {"armor_012", "Yggdrasil Bangle"}, {"armor_011", "Central Stratum Bangle"}, {"armor_010", "Beast Bangle"}, {"armor_009", "Flower Bangle"}, {"armor_008", "Crimson Bangle"}, {"armor_007", "Chloe's Bracelet"}, {"armor_006", "Dagger Bangle"}, {"armor_005", "Bone Bangle"}, {"armor_004", "Stone Bangle"}, {"armor_003", "Thistle Bangle"}, {"armor_002", "Crude Bangle"}, {"armor_001", "Worn Bangle"}, }; // carapaces vars.equipments_2 = new Dictionary<string, string> { {"shield_009", "Luiseach's Carapace"}, {"shield_008", "Primordial Heirloom"}, {"shield_007", "Blessed Carapace"}, {"shield_006", "High Enhancer"}, {"shield_005", "Impact Carapace"}, {"shield_004", "Pyroflective Carapace"}, {"shield_003", "Reflective Carapace"}, {"shield_002", "Enhancer"}, {"shield_001", "Protective Carapace"}, }; // materials vars.materials = new Dictionary<string, string> { {"parts_lv2_b", "Experimental Amplifier"}, {"parts_lv2_c", "Mixed Parts"}, {"parts_lv3_b", "Obsolete Core"}, {"parts_lv3_c", "Antiquated Parts"}, {"parts_lv4_a", "New Model Core"}, {"parts_lv4_b", "Magic Amplifier"}, {"parts_lv4_c", "New Model Parts"}, {"parts_lv5_a", "Special Alloy Core"}, {"parts_lv5_b", "Special Alloy Amplifier"}, {"parts_lv5_c", "Special Alloy Part"}, {"parts_lv6_a", "Origin Gem Core"}, {"parts_lv6_b", "Administrator's Amplifier"}, {"parts_lv6_c", "Highest-grade Parts"}, {"parts_s5000_a", "Unidentified Core"}, {"parts_s5000_b", "Unidentified Amplifier"}, {"parts_s5000_c", "Unidentified Transformer"}, }; // grimoires vars.grimoires = new Dictionary<string, string> { {"shop_line_up", "Grimoire"}, }; vars.obj_count = new Dictionary<string, int> { {"parts_lv2_b", 2}, {"parts_lv2_c", 2}, {"parts_lv3_b", 2}, {"parts_lv3_c", 2}, {"parts_lv4_a", 2}, {"parts_lv4_b", 4}, {"parts_lv4_c", 4}, {"parts_lv5_a", 3}, {"parts_lv5_b", 4}, {"parts_lv5_c", 4}, {"parts_lv6_a", 7}, {"parts_lv6_b", 9}, {"parts_lv6_c", 9}, {"parts_s5000_a", 3}, {"parts_s5000_b", 3}, {"parts_s5000_c", 3}, {"shop_line_up", 12}, }; // totems vars.assists = new Dictionary<string, string> { {"assist_012", "Cetus"}, {"assist_011", "Ilion"}, {"assist_010", "Typhon"}, {"assist_009", "Chiron"}, {"assist_008", "Ares"}, {"assist_007", "Lyra"}, {"assist_006", "Spica"}, {"assist_005", "Regulus"}, {"assist_004", "Carcinus"}, {"assist_003", "Gemini"}, {"assist_002", "Taurus"}, {"assist_001", "Krios"}, }; // relics vars.passives = new Dictionary<string, string> { {"damage_up_grounded", "Chain Belt"}, {"damage_up_airborne", "Sanguinary Raven"}, {"damage_up_swimming", "Attuner's Pendant"}, {"damage_up_skillcategory_combo", "Echo Device"}, {"damage_up_skillcategory_repeat", "Pure Floral Necklace"}, {"damage_up_skillcategory_defence", "Arena Tower Demon Mask"}, {"damage_up_skillcategory_auto", "House Milius Earrings"}, {"damage_up_skillcategory_special", "Cracked Magicite Dagger"}, {"damage_up_maxhp", "Magic Strand Charm"}, {"damage_up_minhp", "Jagged Crystal"}, {"damage_up_sp_gauge", "Priestess' Tears"}, {"damage_up_debuffed", "Battered Grimoire"}, {"damage_up_targetdebuffed", "Vivid Claws"}, {"damage_up_targetstunned", "Cleaner's Tag"}, {"reduce_skill_cooldown", "Eye of the Ancients"}, {"stamina_damage_up_a", "Blighted Talisman"}, {"stamina_damage_up_b", "Mysterious Glowing Can"}, {"debuff_damage_up_a", "Survey Team Gauntlet"}, {"debuff_damage_up_b", "Sorcerer's Gauntlet"}, {"restore_sp_up_a", "Chief Attuner's Ring"}, {"restore_sp_up_b", "Nameless Priestess' Ring"}, {"onattack_restorehp", "Declan's Ring"}, {"onattack_restorehp_damage", "Cain's Ring"}, {"onattack_instantkill", "Abelia's Ring"}, {"onkill_restorehp", "Helix Crystal"}, {"onkill_restoresp", "Attuner's Earrings"}, {"onkill_reduce_cooldowns", "Magicite Hairpin"}, {"onkill_drops", "Headless Gold Statue"}, {"damage_cut_physic", "Tarnished Tag"}, {"damage_cut_debuff_down", "Laborer's Tag"}, {"damage_cut_debuffed", "Bloodstained Stuffed Toy"}, {"damage_cut_maxhp", "Beast Horn Ornament"}, {"damage_cut_minhp", "Effigy"}, {"damage_cut_sp_gauge", "Crystallized Fusion"}, {"experience_up", "Blighted Dice"}, {"gold_up", "Eye of the Beast"}, {"junk_up", "Eye of the Homunculus"}, {"higher_mobility", "Leg Enhancement Gear"}, {"debuff_cut_burn", "Crimson Ribbon"}, {"dodge_long", "Evasive Fragrance"}, {"exploration_charge_short", "Enhancement Gear"}, {"heal_short", "Ward Propagator"}, {"reduce_gravity", "Incomplete Gear"}, {"ending_flag", "Lilia's Blighted Ring"}, }; vars.bosses = new Dictionary<string, string> { { "BP_e5030_Rogue_C", "Lito, the Child Test Subject"}, { "BP_e5110_Gunman_C", "Yolvan, the Black-Winged Huntsman"}, { "BP_e6040_Darker_C", "Caladrius"}, { "BP_e0030_Guard_C", "Old Upper Stratum Guard"}, { "BP_e0122_Wheeler_C", "Squad Leader, Mining Unit 1"}, { "BP_e5200_Pounder_C", "Garm, the Giant Gravedigger"}, { "BP_e0162_Gang_C", "Steeple Executioner"}, { "BP_e5060_Beast_C", "Shackled Beast"}, { "BP_e6000_Rider_C", "Veol, the Crazed Wolf"}, { "BP_e0203_Scarab_C", "Roller: Giant Orb"}, { "BP_e6010_Cluster_Mode1_C", "King of the Garbage Heap P1"}, { "BP_e6010_Cluster_Mode3_C", "King of the Garbage Heap"}, { "BP_e5230_Finder_C_Quarry_001_Zone_008", "Lars, the Lurker of the Depths 1"}, { "BP_e5230_Finder_C_Quarry_001_Zone_019", "Lars, the Lurker of the Depths 2"}, { "BP_e5230_Finder_002_C", "Lars, the Lurker of the Depths 3"}, { "BP_e6050_Master_C", "Gilroy, the Administrator"}, { "BP_e0252_Ninja_C", "Combat Puppet: No. 20"}, { "BP_e0253_Ninja_C", "Combat Puppet: No. 14"}, { "BP_e0262_Komuso_C", "Combat Puppet: No. 56"}, { "BP_e5050_Ronin_C", "Combat Puppet: No. 7"}, { "BP_e0281_banshee_C", "Marionette: No. 47"}, { "BP_e0233_Researcher_C", "Professor Eliza"}, { "BP_e6030_Owner_C", "Declan, the Fallen Sorcerer"}, { "BP_e2030_Sector_C", "Velnest"}, { "BP_e6020_Director_C", "Velgrynd"}, { "BP_e6051_Master_C", "Gilroy, the Administrator (Armed Form)"}, { "BP_e5003_Reaper_C", "Aggressor"}, { "BP_e5070_Witch_C", "Luiseach, the Iron Witch"}, // { "BP_e0500_Tentacle_C", "Rooted Primordial Beast"}, { "BP_e5010_Lancer_C", "Mad Knight Reibolg 1"}, { "BP_e5012_Lancer_C", "Mad Knight Reibolg 2"}, // { "BP_e0510_Ray_C", "Soaring Beast of Origin"}, { "BP_e0222_Security_C", "Velius - Captain of the Guard"}, { "BP_e6052_Master_C", "Gilroy, the Administrator (Absolute Form)"}, { "BP_e6053_Master_C", "Gilroy, the Administrator (Absolute Form) B"}, }; vars.bosses_rooms = new Dictionary<string, string> { { "Ruins_001_Zone_012", "Lito, the Child Test Subject"}, { "Street_001_Zone_004", "Yolvan, the Black-Winged Huntsman"}, { "Street_001_Zone_017", "Old Upper Stratum Guard"}, { "Mine_001_Zone_004", "Squad Leader, Mining Unit 1"}, { "Mine_001_Zone_017", "Garm, the Giant Gravedigger"}, { "Tower_001_Zone_010", "Steeple Executioner"}, { "Tower_001_Zone_016", "Shackled Beast"}, { "Forest_001_Zone_022", "Veol, the Crazed Wolf"}, { "Swamp_001_Zone_004", "Roller: Giant Orb"}, { "Swamp_001_Zone_015", "King of the Garbage Heap"}, { "Quarry_001_Zone_008", "Lars, the Lurker of the Depths 1"}, { "Quarry_001_Zone_019", "Lars, the Lurker of the Depths 2"}, { "Quarry_001_Zone_022", "Lars, the Lurker of the Depths 3"}, { "Center_001_Zone_001", "Gilroy, the Administrator"}, { "Kowloon_001_Zone_048", "Combat Puppet: No. 20"}, { "Kowloon_001_Zone_049", "Combat Puppet: No. 14"}, { "Kowloon_001_Zone_050", "Combat Puppet: No. 56"}, { "Kowloon_001_Zone_051", "Combat Puppet: No. 7"}, { "Paradise_001_Zone_008", "Marionette: No. 47"}, { "Garden_001_Zone_005", "Professor Eliza"}, { "Paradise_001_Zone_018", "Declan, the Fallen Sorcerer"}, { "Factory_001_Zone_010", "Velnest"}, { "Factory_001_Zone_017", "Velgrynd"}, { "Labo_001_Zone_020", "Gilroy, the Administrator (Armed Form)"}, { "Labo_001_Zone_003", "Aggressor"}, { "Garden_001_Zone_011", "Luiseach, the Iron Witch"}, //{ "Quarry_001_Zone_031", "Mad Knight Reibolg 1"}, { "Roots_001_Zone_001", "Mad Knight Reibolg 2"}, { "Summit_001_Zone_021", "Velius - Captain of the Guard"}, { "Summit_001_Zone_030", "Gilroy, the Administrator (Absolute Form)"}, }; vars.bossesDefaultOff = new HashSet<string> { "BP_e6010_Cluster_Mode1_C", "BP_e5110_Gunman_C", "BP_e0252_Ninja_C", "BP_e0253_Ninja_C", "BP_e0262_Komuso_C", "BP_e6052_Master_C", "BP_e6053_Master_C", }; vars.restpoints = new Dictionary<string, string> { //{"forest_bridge", "Crimson Forest Bridge"}, //{"sys_init", "Place of Awakening"}, //{"sys_post_event", "Place of the Forsaken"}, {"ruins_first", "Subterranean Lab"}, {"ruins_lab", "Test Subject Wing"}, {"crossroad_camp", "Abandoned Attuner Tent"}, {"slum_camp", "Private Quarters"}, {"street_clocktower", "Clock Tower Plaza - Entrance"}, {"street_towergate", "Tethered Steeple - Entrance"}, {"mine_room1", "Broken Apparatus"}, {"mine_room2", "Rest Area"}, {"mine_room3", "Floral Cavern"}, {"sewer_left", "Attuner's Respite"}, {"tower_high", "Decaying Room"}, {"tower_low", "Assembly Hall"}, {"tower_gate", "Forest Barrier - Entrance"}, {"forest_tree", "Great Tree of the Crimson Forest"}, {"forest_village", "Crimson Forest Settlement"}, {"swamp_lake", "Cleaner's Refuge"}, {"swamp_center", "Discarded Bench"}, {"swamp_trash", "Administrative Section"}, {"quarry_room", "Fungal Refuge"}, {"quarry_room2", "Central Room"}, {"quarry_room3", "Unblighted Path"}, {"kowlon_room4", "Steel District Bench"}, {"kowlon_room", "Combat Puppet Quarters"}, {"kowlon_room2", "Arena Tower"}, {"kowloon_room3", "Before the Guiding Bridge"}, {"paradice_room", "Sage's Study"}, {"paradice_room2", "Underground Observatory"}, {"paradice_room3", "The Lord's Chambers"}, {"garden_room", "Main Academy Building Entrance"}, {"garden_room2", "Central Plaza"}, {"garden_room3", "Vacant Courtyard"}, {"factory_room", "Runaway's Abode"}, {"factory_room2", "Labor Regulation Center"}, {"factory_room3", "Control Center"}, {"labo_room", "Great Orb of Intellect"}, {"labo_room2", "Rooftop"}, {"labo_room3", "Forbidden Text Archive"}, {"estate_room", "Dust-covered Sofa"}, {"center_bench", "Central City Bench"}, {"summit_lobby", "Empyrean Parasol Interior"}, {"summit_last", "Before the Throne"}, {"roots_top", "Path of Origin"}, {"roots_left", "Ancient Resting Place"}, {"roots_right", "Ritual Site"}, }; // SETTINGS settings.Add("load_remover", true, "Load Remover"); settings.SetToolTip("load_remover", "Pause timer during game loadings, only affects Game Time"); settings.Add("config_split", true, "Splits Configuration"); settings.Add("split_ending", true, "Game Endings", "config_split"); settings.SetToolTip("split_ending", "Split when reaching Ending A or B"); settings.Add("split_boss", true, "Boss Kill", "config_split"); settings.SetToolTip("split_boss", "Split when killing Bosses"); foreach (KeyValuePair<string, string> kvp in vars.bosses) { settings.Add(kvp.Key, !vars.bossesDefaultOff.Contains(kvp.Key), kvp.Value, "split_boss"); settings.SetToolTip(kvp.Key, kvp.Key); } settings.Add("split_boss_room", false, "Boss Rooms", "config_split"); settings.SetToolTip("split_boss_room", "Split when entering a boss room"); foreach (KeyValuePair<string, string> kvp in vars.bosses_rooms) { settings.Add(kvp.Key, true, kvp.Value, "split_boss_room"); settings.SetToolTip(kvp.Key, kvp.Key); } settings.Add("split_restpoint", false, "Respites", "config_split"); settings.SetToolTip("split_restpoint", "Split when reaching a respite"); foreach (KeyValuePair<string, string> kvp in vars.restpoints) { settings.Add(kvp.Key, true, kvp.Value, "split_restpoint"); settings.SetToolTip(kvp.Key, kvp.Key); } settings.Add("split_aptitude", false, "Abilities", "config_split"); settings.SetToolTip("split_aptitude", "Split when grabbing an ability"); foreach (KeyValuePair<string, string> kvp in vars.aptitudes) { settings.Add(kvp.Key, true, kvp.Value, "split_aptitude"); settings.SetToolTip(kvp.Key, kvp.Key); } settings.Add("split_key", false, "Keys", "config_split"); settings.SetToolTip("split_key", "Split when grabbing a key"); foreach (KeyValuePair<string, string> kvp in vars.keys) { settings.Add(kvp.Key, true, kvp.Value, "split_key"); settings.SetToolTip(kvp.Key, kvp.Key); } settings.Add("split_quest", false, "Quest Items", "config_split"); settings.SetToolTip("split_quest", "Split when grabbing a quest item"); foreach (KeyValuePair<string, string> kvp in vars.quests) { settings.Add(kvp.Key, true, kvp.Value, "split_quest"); settings.SetToolTip(kvp.Key, kvp.Key); } settings.Add("split_spirit", false, "Homunculi", "config_split"); settings.SetToolTip("split_spirit", "Split when grabbing an Homunculi"); foreach (KeyValuePair<string, string> kvp in vars.spirits) { settings.Add(kvp.Key, true, kvp.Value, "split_spirit"); settings.SetToolTip(kvp.Key, kvp.Key); } settings.Add("split_equipment_1", false, "Bracelets", "config_split"); settings.SetToolTip("split_equipment_1", "Split when grabbing a bracelet"); foreach (KeyValuePair<string, string> kvp in vars.equipments_1) { settings.Add(kvp.Key, true, kvp.Value, "split_equipment_1"); settings.SetToolTip(kvp.Key, kvp.Key); } settings.Add("split_equipment_2", false, "Carapaces", "config_split"); settings.SetToolTip("split_equipment_2", "Split when grabbing a carapace"); foreach (KeyValuePair<string, string> kvp in vars.equipments_2) { settings.Add(kvp.Key, true, kvp.Value, "split_equipment_2"); settings.SetToolTip(kvp.Key, kvp.Key); } settings.Add("split_assist", false, "Totems", "config_split"); settings.SetToolTip("split_assist", "Split when grabbing a totem"); foreach (KeyValuePair<string, string> kvp in vars.assists) { settings.Add(kvp.Key, true, kvp.Value, "split_assist"); settings.SetToolTip(kvp.Key, kvp.Key); } settings.Add("split_passive", false, "Relics", "config_split"); settings.SetToolTip("split_passive", "Split when grabbing a relic"); foreach (KeyValuePair<string, string> kvp in vars.passives) { settings.Add(kvp.Key, true, kvp.Value, "split_passive"); settings.SetToolTip(kvp.Key, kvp.Key); } settings.Add("split_material", false, "Components", "config_split"); settings.SetToolTip("split_material", "Split when pickup up a component"); foreach (KeyValuePair<string, string> kvp in vars.materials) { settings.Add(kvp.Key, true, kvp.Value, "split_material"); settings.SetToolTip(kvp.Key, kvp.Key); for (int i = 1; i <= vars.obj_count[kvp.Key]; ++i) { var key = kvp.Key + "_" + i.ToString(); var text = i.ToString() + "/" + vars.obj_count[kvp.Key].ToString(); settings.Add(key, true, text, kvp.Key); } } settings.Add("split_grimoire", false, "Grimoires", "config_split"); settings.SetToolTip("split_grimoire", "Split when pickup up a grimoire"); foreach (KeyValuePair<string, string> kvp in vars.grimoires) { for (int i = 1; i <= vars.obj_count[kvp.Key]; ++i) { settings.Add(kvp.Key + "_" + i.ToString(), true, i.ToString() + "/" + vars.obj_count[kvp.Key].ToString(), "split_grimoire"); } } } init { byte[] exeMD5HashBytes = new byte[0]; using (var md5 = System.Security.Cryptography.MD5.Create()) { using (var s = File.Open(modules.First().FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { exeMD5HashBytes = md5.ComputeHash(s); } } var MD5Hash = exeMD5HashBytes.Select(x => x.ToString("X2")).Aggregate((a, b) => a + b); vars.GetName = new Func<int, string>((int comparison) => { int block = comparison >> 16; int offset = comparison & 0xFFFF; DeepPointer header = new DeepPointer(vars.fNamePool + 0x10 + (0x8 * block)); IntPtr ptr = header.Deref<IntPtr>(game) + (0x2 * offset); Int16 len = (Int16)(game.ReadValue<Int16>(ptr) >> 6); return game.ReadString(ptr + 0x2, len); }); vars.GetObject = new Func<int, IntPtr>((int key) => { int chunk = key / 0x10000; int index = key % 0x10000; IntPtr obj = new DeepPointer(vars.GUObjectArray + 0x10, 0x8 * chunk, index * 0x18).Deref<IntPtr>(game); return obj; }); switch(MD5Hash) { case "2D37E3BAAC225F78EEE1B1CBB17D227E": { vars.fNamePool = 0x07E95AC0; vars.GUObjectArray = 0x07F4C820; version = "Steam 1.1.1"; break; } case "DC8AA145769EEE84068846F2B0446F3A": { vars.fNamePool = 0x07E92A40; vars.GUObjectArray = 0x07F497A0; version = "Steam 1.1.0"; break; } case "E1B61EB5CE59F921CA9D3A671A197BFA": { vars.fNamePool = 0x07CC14C0; vars.GUObjectArray = 0x07D78220; version = "Steam 1.0.4"; break; } case "4E99ACB034B5729EB3B94C43C184C6F0": { vars.fNamePool = 0x07CBF2C0; version = "Steam 1.0.3"; break; } case "F8A689E17C2736A8BF2F0A5DF88C35FD": { version = "Steam 1.0.2"; break; } case "CEB55A8722FB508280E938D3CCBBD7F4": { version = "Steam Early Access, 0.5.0"; break; } case "D92A11D9596FA04062CDD99F1C80CB49": { version = "Steam Early Access, 0.5.1"; break; } default: { var gameMessage = MessageBox.Show( "Unrecognized game version\n\n"+ "Please report this error in ENDER: Serie Discord\n"+ "with the following hash:\n\n"+MD5Hash+"\n\n"+ "Press OK to copy the above info to the clipboard and close this message.", "Ender Magnolia Autosplitter | LiveSplit", MessageBoxButtons.OKCancel,MessageBoxIcon.Warning ); if (gameMessage == DialogResult.OK) Clipboard.SetText(MD5Hash); version = "Unknown"; break; } } vars.splitsDone = new HashSet<string>(); vars.ready = false; vars.respites = new Dictionary<string, int>(); } start { vars.splitsDone = new HashSet<string>(); vars.ready = false; vars.respites = new Dictionary<string, int>(); if (old.LevelBuildDataId != 0 && old.LevelBuildDataId != current.LevelBuildDataId) { vars.lastLevel = old.LevelBuildDataId; } bool start = vars.lastLevel == vars.TitleLevelID && current.LevelBuildDataId == vars.InGameLevelID && old.LevelBuildDataId != current.LevelBuildDataId; return start; } update { if (version == "Unknown" || version == "") return false; if (old.LevelBuildDataId != 0 && old.LevelBuildDataId != current.LevelBuildDataId) { vars.lastLevel = old.LevelBuildDataId; } //print("->" + vars.GetName(current.LevelName)); return true; } isLoading { return settings["load_remover"] && (current.isLoading || current.switchingZone); } reset { return current.LevelBuildDataId == vars.TitleLevelID && old.LevelBuildDataId != current.LevelBuildDataId; } split { var CheckInventorySplit = new Func<bool>(() => { var ptrs = new Dictionary<string, IntPtr>{ {"split_aptitude", (IntPtr)current.AptitudeInventory}, {"split_key", (IntPtr)current.KeyInventory}, {"split_quest", (IntPtr)current.QuestInventory}, {"split_spirit", (IntPtr)current.SpiritInventory}, {"split_equipment_1", (IntPtr)current.EquipmentInventory}, {"split_equipment_2", (IntPtr)current.EquipmentInventory}, {"split_passive", (IntPtr)current.PassiveInventory}, {"split_assist", (IntPtr)current.AssistInventory}, {"split_material", (IntPtr)current.MaterialInventory}, {"split_grimoire", (IntPtr)current.StatsInventory}, }; var items = new HashSet<IntPtr> {}; foreach (var kvp in ptrs) if (settings[kvp.Key]) items.Add(kvp.Value); bool split = false; foreach (var ptr in items) { int count = new DeepPointer(ptr + 0x60).Deref<int>(game); for (int i = 0; i < count; ++i) { int item = new DeepPointer(ptr + 0x58, i * 0x14).Deref<int>(game); string str = vars.GetName(item).ToLower(); if (vars.obj_count.ContainsKey(str)) { int quantity = new DeepPointer(ptr + 0x58, (i * 0x14) + 0x8).Deref<int>(game); str = str + "_" + quantity.ToString(); } if (!settings.ContainsKey(str) || !settings[str] || vars.splitsDone.Contains(str)) continue; vars.splitsDone.Add(str); split = true; if (vars.ready) return true; } } return split; }); vars.ready = vars.ready || (current.LevelName != null && current.timeSinceStartup > 1 && !CheckInventorySplit()); if (!vars.ready) return false; if (settings["split_ending"] && old.SaveBackup != current.SaveBackup && current.LevelName > 0 && vars.GetName(current.LevelName) == "Summit_001_Zone_030") return true; var CheckBossSplit = new Func<int, bool>((int weakPTR) => { IntPtr obj = vars.GetObject(weakPTR); int name = new DeepPointer(obj + 0x18).Deref<int>(game); string str = vars.GetName(name); if (!vars.bosses.ContainsKey(str)) str += "_" + vars.GetName(current.LevelName); if (!vars.bosses.ContainsKey(str) || !settings[str] || vars.splitsDone.Contains(str)) return false; bool isDead = new DeepPointer(obj + 0x8D8, 0x3B).Deref<bool>(game); current.dead = isDead; if (current.dead && !old.dead) { vars.splitsDone.Add(str); return true; } return false; }); if (settings["split_boss"] && current.EnemyTargetsCount > 0 && CheckBossSplit(current.EnemyTargetObjectIndex)) return true; if (settings["split_boss_room"] && current.LevelName != 0 && old.LevelName != current.LevelName) { string str = vars.GetName(current.LevelName); if (!settings[str] || vars.splitsDone.Contains(str)) return false; vars.splitsDone.Add(str); return true; } if (CheckInventorySplit()) return true; if (settings["split_restpoint"]) { int count = current.CachedIconsCount; IntPtr ptr = (IntPtr)current.CachedIcons; for (int i = 0; i < count; ++i) { int name = new DeepPointer(ptr + i * 0x8, 0x5E0).Deref<int>(game); if (name > 0) { string str = vars.GetName(name); if (string.IsNullOrEmpty(str) || !vars.restpoints.ContainsKey(str) || !settings[str] || vars.splitsDone.Contains(str)) continue; int visible = new DeepPointer(ptr + i * 0x8, 0xDC).Deref<int>(game); if (!(vars as IDictionary<string, object>).ContainsKey("respites")) vars.respites = new Dictionary<string, int>(); if (visible == 4 && vars.respites.ContainsKey(str) && vars.respites[str] == 2) { vars.respites[str] = visible; vars.splitsDone.Add(str); return true; } vars.respites[str] = visible; } } } return false; } shutdown { }