process("POP.EXE") -- Startup local current = {} local old = {} function clearSplits() for k,v in pairs(splits) do print("clearing ", k) v["done"] = false end end function startup() clearSplits() end -- Get game state function state() -- Some memory value that reliably changes when 'New Game' is pressed. current.startValue = readAddress('int', 0x6BC980) -- Prince's position current.xPos = readAddress('float', 0x00699474, 0xC, 0x30) current.yPos = readAddress('float', 0x00699474, 0xC, 0x34) current.zPos = readAddress('float', 0x00699474, 0xC, 0x38) current.xCam = readAddress('float', 0x006DA1B0, 0xC, 0x30) -- The Vizier's health where 0 is unharmed and 4 is dead. current.vizierHealth = readAddress('int', 0x0040E518, 0x6C, 0x18, 0x4, 0x44, 0x0) end -- Main functions function start() --Detecting if the game has started on the balcony. evalSplit(splits["FarahBalcony"]) return splits["FarahBalcony"]["done"] and current.startValue == 1 and current.xCam <= -92.8 end function reset() return splits["FarahBalcony"]["done"] and current.xCam <= -92 and current.xCam > -92.8 end --function update() --end -- Position range detection function inXRange(xMin, xMax) return current.xPos >= xMin and current.xPos <= xMax end function inYRange(yMin, yMax) return current.yPos >= yMin and current.yPos <= yMax end function inZRange(zMin, zMax) return current.zPos >= zMin and current.zPos <= zMax end function splitByXYZ(xMin, xMax, yMin, yMax, zMin, zMax) return inXRange(xMin, xMax) and inYRange(yMin, yMax) and inZRange(zMin, zMax) end -- Split Logic function split() local res = false for name,split in pairs(splits) do if split["enable"] and not split["done"] then res = res or hasSplitUpdated(split) end if res and name ~= "FarahBalcony" then splits["FarahBalcony"]["done"] = false end end if splitByXYZ(-477.88, -477, -298, -297.1, -0.5, -0.4) then splits["SoTLU"]["done"] = false; end if splitByXYZ(658.26, 661.46, 210.92, 213.72, 12.5, 30) then splits["AboveCredits"]["done"] = true; end return res end function evalSplit(split) local res = split["func"]() if res then split["done"] = res end end function hasSplitUpdated(split) local old = split["done"] if not split["done"] then evalSplit(split) else return false end local new = split["done"] return not (old == new) end -- Splits splits = { ["FarahBalcony"] = { enable = true; done = false; func = function() return splitByXYZ(-103.264, -103.262, -4.8, -4.798, 1.341, 1.343) end; }, -- "Split just before the first save prompt" ["GasStation"] = { enable = true; done = false; func = function() return splitByXYZ(252, 258, 130.647, 134, 22.999, 23.001) end; }, -- "Split on starting the first fight after the CGI cutscene" ["SandsUnleashed"] = { enable = true; done = false; func = function() return splitByXYZ(-6.177, -6.175, 62.905, 62.907, 7.604, 7.606) end; }, -- "Split on entering the first guest room" ["FirstGuestRoom"] = { enable = true; done = false; func = function() return splitByXYZ(30.297, 30.299, 42.126, 42.128, 12.998, 13) end; }, -- "Split on entering the Sultan's chamber at the cutscene" ["SultanChamberZipless"] = { enable = true; done = false; func = function() return splitByXYZ(98.445, 98.447, 39.567, 39.57, -8.96, -8.958) end; }, -- "Split at the death abuse in Sultan's chamber" ["SultanChamber"] = { enable = false; done = false; func = function() return splitByXYZ(134.137, 134.139, 54.990, 54.992, -32.791, -32.789) end; }, -- "Split on exiting the palace defense system" ["PalaceDefence"] = { enable = true; done = false; func = function() return splitByXYZ(4.547, 8.851, 40.494, 47.519, -39.001, -38.999) end; }, -- "Split on starting the fight with the Sand King" ["DadStart"] = { enable = true; done = false; func = function() return splitByXYZ(6.714, 6.716, 57.698, 57.7, 21.005, 21.007) end; }, -- "Split at the end of the fight on loading the next area" ["DadDead"] = { enable = true; done = false; func = function() return splitByXYZ(-6.001, -5.999, -18.6, -18.4, 1.998, 2.001) end; }, -- "Split on hitting the button to let Farah enter Warehouse" ["TheWarehouse"] = { enable = true; done = false; func = function() return splitByXYZ(-73.352, -71.233, -28.5, -26.868, -1.001, -0.818) end; }, -- "Split on entering the zoo" ["TheZoo"] = { enable = true; done = false; func = function() return splitByXYZ(-141.299, -139.797, -47.21, -42.801, -31.1, -30.9) end; }, -- "Split at the 'Atop a bird cage' save vortex" ["BirdCage"] = { enable = true; done = false; func = function() return splitByXYZ(-211, -208, -23, -21, -9, -8.8) end; }, -- "Split at the start of cliffs and waterfall" ["CliffWaterfalls"] = { enable = true; done = false; func = function() return splitByXYZ(-233.6, -231.4, 33.7, 35, -42.6, -42.4) end; }, -- "Split at the end of cliffs and Waterfall" ["TheBathsZipless"] = { enable = true; done = false; func = function() return splitByXYZ(-215.85, -214.089, 54.261, 58.699, -43.501, -43.499) end; }, -- "Split on death abuse at the start of baths" ["TheBaths"] = { enable = false; done = false; func = function() return splitByXYZ(-211.427, -211.425, 56.602, 56.604, -43.501, -43.499) end; }, -- "Split on obtaining the second sword at baths" ["SecondSword"] = { enable = true; done = false; func = function() return splitByXYZ(-106.819, -106.817, 81.097, 81.099, -27.269, -27.267) end; }, -- "Split at the start of daybreak" ["TheDaybreak"] = { enable = true; done = false; func = function() return splitByXYZ(-76, -70, 192.4, 197.6, -56.6, -54) end; }, -- "Split on death abuse in the mess hall" ["TheMesshall"] = { enable = false; done = false; func = function() return splitByXYZ(-183.267, -183.265, 234.685, 234.687, -37.528, -37.526) end; }, -- "Split near the first lever at Drawbridge Tower" ["DrawbridgeTower"] = { enable = true; done = false; func = function() return splitByXYZ(-267, -262, 232, 267, -35.6, -35.5) end; }, -- "Split at the end of the collapsing bridge" ["BrokenBridge"] = { enable = true; done = false; func = function() return splitByXYZ(-265, -257, 159, 167, -13.6, -13.4) end; }, -- "Split on entering the caves after the door" ["TheCavesZipless"] = { enable = true; done = false; func = function() return splitByXYZ(-303, -297.5, 112, 113.5, -56.1, -55.9) end; }, -- "Split on the beam at the start of Waterfall" ["TheCaves"] = { enable = false; done = false; func = function() return splitByXYZ(-246.839, -241.677, 78.019, 87.936, -71.731, -70.7) end; }, -- "Split at the end of the descent in Waterfall" ["TheWaterfall"] = { enable = true; done = false; func = function() return splitByXYZ(-242, -240.5, 79.5, 83, -121, -118) end; }, -- "Split on entering the underground reservoir" ["TheUGReservoirZipless"] = { enable = true; done = false; func = function() return splitByXYZ(-121, -110, -9, -7, -154.1, -153.9) end; }, -- "Split on exiting the underground reservoir" ["TheUGReservoir"] = { enable = false; done = false; func = function() return splitByXYZ(-51.477, -48.475, 72.155, 73.657, -24.802, -24.799) end; }, -- "Split on entering the hall of learning" ["HallofLearning"] = { enable = true; done = false; func = function() return splitByXYZ(73, 79, 161, 163, -24.1, -23.9) end; }, -- "Split on death abuse at the end of observatory" ["TheObservatory"] = { enable = false; done = false; func = function() return splitByXYZ(139.231, 139.233, 162.556, 162.558, -29.502, -29.5) end; }, -- "Split on exiting the observatory" ["ObservatoryExit"] = { enable = true; done = false; func = function() return splitByXYZ(137, 141, 164, 164.67, -29.5, -29.2) end; }, -- "Split on exiting hall of learning courtyards" ["HoLCourtyardsExit"] = { enable = true; done = false; func = function() return splitByXYZ(72, 77, 90, 95.7, -27.1, -26.9) end; }, -- "Split on entering the prison" ["TheAzadPrison"] = { enable = true; done = false; func = function() return splitByXYZ(190, 195, -21, -19, -17.6, -17.3) end; }, -- "Split on entering the torture chamber" ["TortureChamberZipless"] = { enable = true; done = false; func = function() return splitByXYZ(187.5, 192.5, -39, -37.5, -119.1, -118.9) end; }, -- "Split on death abuse at the start of torture chamber" ["TortureChamber"] = { enable = false; done = false; func = function() return splitByXYZ(189.999, 190.001, -43.278, -43.276, -119.001, -118.999) end; }, -- "Split on entering the elevator" ["TheElevator"] = { enable = true; done = false; func = function() return splitByXYZ(74, 75, -46.751, -43.252, -34, -33) end; }, -- "Split at the start of the long unskippable cutscene" ["TheDreamZipless"] = { enable = true; done = false; func = function() return splitByXYZ(99, 101, -11, -10, -56, -54) end; }, -- "Split at the start of the 'infinite' stairs" ["TheDream"] = { enable = false; done = false; func = function() return splitByXYZ(95.8, 96, -25.1, -24.9, -74.9, -74.7) end; }, -- "Split at the start of the tomb" ["TheTomb"] = { enable = true; done = false; func = function() return splitByXYZ(100.643, 100.645, -11.543, -11.541, -67.588, -67.586) end; }, -- "Split at the start of the ascent back up the Tower of Dawn" ["TowerofDawn"] = { enable = true; done = false; func = function() return splitByXYZ(35.5, 35.7, -50, -39, -32, -30) end; }, -- "Split on the Ladder near the setting sun save" ["SettingSun"] = { enable = true; done = false; func = function() return splitByXYZ(60, 61, -58, -57, 30, 32) end; }, -- "Split on starting the last fight with enemies" ["HonorGlory"] = { enable = true; done = false; func = function() return splitByXYZ(81, 82, -60.3, -59.7, 89, 90) end; }, -- "Split on starting the Vizier fight" ["GrandRewind"] = { enable = true; done = false; func = function() return splitByXYZ(660.376, 660.378, 190.980, 190.983, 0.432, 0.434) end; }, -- "Split on defeating the Vizier or hitting the credits trigger" ["SoTEnd"] = { enable = true; done = false; func = function() return splitByXYZ(658.26, 661.46, 210.92, 213.72, 9.8, 12.5) and (splits["AboveCredits"] ~= nil or current.vizierHealth == 4) end; }, -- "Split on obtaining each life upgrade" ["SoTLU"] = { enable = false; done = false; func = function() return splitByXYZ(-492.608, -492.606, -248.833, -248.831, 0.219, 0.221) end; }, }