Skip to content

Commit

Permalink
Add even more savedata options
Browse files Browse the repository at this point in the history
  • Loading branch information
Dregu committed Aug 18, 2024
1 parent 8abf027 commit 2cad776
Show file tree
Hide file tree
Showing 4 changed files with 230 additions and 50 deletions.
6 changes: 6 additions & 0 deletions max.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,12 @@ uint64_t *Max::chests() { return (uint64_t *)(slot() + 0x418 + 0x120); }

uint16_t *Max::candles() { return (uint16_t *)(slot() + 0x418 + 0x1e0); }

uint32_t *Max::bunnies() { return (uint32_t *)(slot() + 0x418 + 0x198); }

uint8_t *Max::portals() { return (uint8_t *)(slot() + 0x418 + 0x223); }

uint8_t *Max::shards() { return (uint8_t *)(slot() + 0x418 + 0x1F4 + 0xa); }

Pause *Max::pause() {
return (Pause *)((*(size_t *)get_address("slots") + 0x93608));
};
Expand Down
3 changes: 3 additions & 0 deletions max.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@ struct Max {
uint8_t *flames();
uint64_t *chests();
uint16_t *candles();
uint32_t *bunnies();
uint8_t *portals();
uint8_t *shards();
Pause *pause();
uint32_t *timer();
void save_game();
Expand Down
265 changes: 216 additions & 49 deletions ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,51 +48,52 @@ const double f64_zero = 0., f64_one = 1., f64_lo_a = -1000000000000000.0,
f64_hi_a = +1000000000000000.0;

std::array equipment_names{
"Unknown", "Firecrackers", "Flute", "Lantern", "Top", "Disc", "BWand",
"Yoyo", "Slink", "Remote", "Ball", "Wheel", "UVLight",
"", "Firecrackers", "Flute", "Lantern", "Top",
"Disc", "Bubble Wand", "Yoyo", "Slink", "Remote",
"Ball", "Wheel", "UV Light",
};

std::array item_names{
"MockDisc", "SMedal", "Cake", "HouseKey",
"OfficeKey", "CageKey", "EMedal", "FPack",
"Mock Disc", "Snake Medal", "Cake", "House key",
"Office key", "Closet key", "Eel Medal", "Fanny Pack",
};

std::array misc_names{
"HouseOpened",
"OfficeOpened",
"ClosetOpened",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",

"SwitchState",
"MapCollected",
"StampsCollected",
"PencilCollected",
"ChameleonDefeated",
"CRingCollected",
"EatenByChameleon",
"InsertedSMedal",

"EMedalInserted",
"WingsAcquired",
"WokeUp",
"BBWandUpgrade",
"ManticoreEgg65",
"AllCandlesLit",
"SingularityActive",
"ManticoreEggPlaced",

"BatDefeated",
"OstrichFreed",
"OstrichDefeated",
"EelFightActive",
"EelDefeated",
"NoDiscInShrine",
"NoDiscInStatue",
"Unknown",
"House opened",
"Office opened",
"Closet opened",
"",
"",
"",
"",
"",

"Switch state",
"Map collected",
"Stamps collected",
"Pencil collected",
"Chameleon defeated",
"C.Ring collected",
"Eaten by chameleon",
"Snake Medal inserted",

"Eel Medal inserted",
"Wings acquired",
"Woke up",
"B.B.Wand upgrade",
"65th Egg acquired",
"All candles lit",
"Torus active",
"65th Egg placed",

"Bat defeated",
"Ostrich freed",
"Ostrich defeated",
"Eel fight active",
"Eel defeated",
"No disc in shrine",
"No disc in statue",
"",
};

std::array egg_names{
Expand Down Expand Up @@ -162,6 +163,45 @@ std::array egg_names{
"Golden Egg",
};

std::array bunny_names{
"Tutorial Bunny",
"Illegal 1",
"Origami Bunny",
"Crow Bunny",
"Ghost Bunny",
"Illegal 2",
"Fish Mural Bunny",
"Map Numbers Bunny",
"TV Bunny",
"UV Bunny",
"Bulb Bunny",
"Chinchilla Bunny",
"Illegal 3",
"Illegal 4",
"Illegal 5",
"Bunny Mural Bunny",
"Illegal 6",
"Illegal 7",
"Illegal 8",
"Illegal 9",
"Illegal 10",
"Illegal 11",
"Duck Bunny",
"Illegal 12",
"Illegal 13",
"Ghost Dog Bunny",
"Illegal 14",
"Illegal 15",
"Dream Bunny",
"Illegal 16",
"Floor Is Lava Bunny",
"Spike Room Bunny",
};

std::array portal_names{
"Eel", "Frog", "Fish", "Bear", "Dog", "Bird", "Squirrel", "Hippo",
};

const std::map<std::string, PLAYER_INPUT> notes{
{"A4", (PLAYER_INPUT)(PLAYER_INPUT::RIGHT | PLAYER_INPUT::LB)},
{"A#4",
Expand Down Expand Up @@ -333,8 +373,8 @@ bool IsKeyChordReleased(ImGuiKeyChord key_chord) {

template <std::size_t SIZE, typename T>
void Flags(const std::array<const char *, SIZE> names_array, T *flag_field,
bool show_number = true) {
for (int idx{0}; idx < SIZE && idx < sizeof(T) * 8; ++idx) {
bool show_number = false, int first = 0) {
for (int idx{first}; idx < SIZE && idx < sizeof(T) * 8; ++idx) {
T value = (T)std::pow(2, idx);
bool on = (*flag_field & value) == value;

Expand Down Expand Up @@ -387,22 +427,108 @@ void UI::DrawPlayer() {
Tooltip("This sets your current room as spawn and runs the save function "
"anywhere.\nIn rooms without a phone you will spawn near the "
"top left corner.");
if (ImGui::CollapsingHeader("Equipment##PlayerEquipment"))
Flags(equipment_names, Max::get().equipment(), false);
if (ImGui::CollapsingHeader("Items##PlayerItems"))
Flags(item_names, Max::get().items(), false);
if (ImGui::CollapsingHeader("Equipment##PlayerEquipment")) {
bool disc = *Max::get().equipment() & (1 << 5);
bool all = *Max::get().equipment() & 0x1FFE;
if (ImGui::Checkbox("Unlock all equipment##UnlockAllEquipment", &all)) {
if (all)
*Max::get().equipment() = 0x1FFE;
else
*Max::get().equipment() = 0;
}
ImGui::Separator();
Flags(equipment_names, Max::get().equipment());
if (!disc && *Max::get().equipment() & (1 << 5) &&
(*Max::get().upgrades() & 0x60000000) == 0)
*Max::get().upgrades() |= 0x20000000;
}
if (ImGui::CollapsingHeader("Items##PlayerItems")) {
bool all = *Max::get().items();
if (ImGui::Checkbox("Unlock all items##UnlockAllItems", &all)) {
if (all) {
*Max::get().items() = 0xFF;
*Max::get().shards() = 2;
*(Max::get().shards() + 12) = 2;
*(Max::get().shards() + 24) = 2;
} else {
*Max::get().items() = 0;
*Max::get().shards() = 0;
*(Max::get().shards() + 12) = 0;
*(Max::get().shards() + 24) = 0;
}
}
ImGui::Separator();
Flags(item_names, Max::get().items());
bool shards[3];
shards[0] = *Max::get().shards();
shards[1] = *(Max::get().shards() + 12);
shards[2] = *(Max::get().shards() + 24);
if (ImGui::Checkbox("##Shard1", &shards[0]))
*Max::get().shards() = shards[0] * 2;
ImGui::SameLine(0, 4);
if (ImGui::Checkbox("##Shard2", &shards[1]))
*(Max::get().shards() + 12) = shards[1] * 2;
ImGui::SameLine(0, 4);
if (ImGui::Checkbox("Kangaroo shards##Shard3", &shards[2]))
*(Max::get().shards() + 24) = shards[2] * 2;
}
if (ImGui::CollapsingHeader("Miscellaneous##PlayerMisc"))
Flags(misc_names, Max::get().upgrades(), false);
if (ImGui::CollapsingHeader("Eggs##PlayerEggs"))
Flags(egg_names, Max::get().eggs(), false);
Flags(misc_names, Max::get().upgrades());
if (ImGui::CollapsingHeader("Eggs##PlayerEggs")) {
bool all = *Max::get().eggs();
if (ImGui::Checkbox("Unlock all eggs##UnlockAllEggs", &all)) {
if (all) {
*Max::get().eggs() = 0xFFFFFFFFFFFFFFFF;
*Max::get().upgrades() |= (1 << 20);
} else {
*Max::get().eggs() = 0;
*Max::get().upgrades() &= ~(1 << 20);
}
}
ImGui::Separator();
Flags(egg_names, Max::get().eggs());
ImGui::CheckboxFlags("65th Egg", Max::get().upgrades(), 1 << 20);
}
if (ImGui::CollapsingHeader("Bunnies##PlayerBunnies")) {
bool all = *Max::get().bunnies() & 0xD2408FDD;
if (ImGui::Checkbox("Unlock legal bunnies##UnlockLegalBunnies", &all)) {
if (all)
*Max::get().bunnies() = 0xD2408FDD;
else
*Max::get().bunnies() = 0;
}
ImGui::Separator();
Flags(bunny_names, Max::get().bunnies());
}
if (ImGui::CollapsingHeader("Candles##PlayerCandles")) {
ImGui::TextWrapped("Only the first 9 candles exist on a vanilla map.");
bool all = *Max::get().candles();
if (ImGui::Checkbox("Unlock legal candles##UnlockAllCandles", &all)) {
if (all) {
*Max::get().candles() = 0x1FF;
} else {
*Max::get().candles() = 0;
}
}
ImGui::Separator();
UnnamedFlags("Candle", Max::get().candles(), 16);
}
if (ImGui::CollapsingHeader("Chests##PlayerChests")) {
ImGui::TextWrapped("Only the first 102 chests exist on a vanilla map.");
UnnamedFlags("Chest", Max::get().chests(), 64);
UnnamedFlags("Chest", Max::get().chests() + 1, 64, 64);
}
if (ImGui::CollapsingHeader("Flames##PlayerFlames")) {
bool all = *Max::get().flames() == 5;
if (ImGui::Checkbox("Place all flames##UnlockAllFlames", &all)) {
for (int i = 0; i < 4; ++i)
if (all) {
*(Max::get().flames() + i) = 5;
} else {
*(Max::get().flames() + i) = 0;
}
}
ImGui::Separator();
ImGui::SliderScalar("Blue Flame / Seahorse##BlueFlameSlider",
ImGuiDataType_U8, Max::get().flames(), &u8_zero,
&u8_five);
Expand All @@ -416,8 +542,38 @@ void UI::DrawPlayer() {
ImGuiDataType_U8, Max::get().flames() + 3, &u8_zero,
&u8_five);
}

if (ImGui::CollapsingHeader("Animal head portals##PlayerPortals")) {
bool all = *Max::get().portals();
if (ImGui::Checkbox("Unlock all portals##UnlockAllPortals", &all)) {
if (all) {
*Max::get().portals() = 0xfe;
*(Max::get().portals() + 1) = 0xfe;
*Max::get().upgrades() &= ~(1 << 27);
*Max::get().upgrades() |= (1 << 28);
} else {
*Max::get().portals() = 0;
*(Max::get().portals() + 1) = 0;
*Max::get().upgrades() &= ~(1 << 27);
*Max::get().upgrades() &= ~(1 << 28);
}
}
ImGui::SeparatorText("Heads seen");
ImGui::PushID("AnimalHeadsSeen");
ImGui::CheckboxFlags("Eel fight active", Max::get().upgrades(), 1 << 27);
Flags(portal_names, Max::get().portals(), false, 1);
ImGui::PopID();
ImGui::PushID("AnimalHeadsUnlocked");
ImGui::SeparatorText("Heads unlocked");
ImGui::CheckboxFlags("Eel", Max::get().upgrades(), 1 << 28);
Flags(portal_names, Max::get().portals() + 1, false, 1);
ImGui::PopID();
}
if (*Max::get().upgrades() & (1 << 28))
*Max::get().upgrades() &= ~(1 << 27);
if (ImGui::CollapsingHeader("Consumables##PlayerConsumables")) {
bool all = false;
ImGui::Checkbox("Max out stats##UnlockMaxStats",
&options["cheat_stats"].value);
ImGui::DragScalar("Health##PlayerHealth", ImGuiDataType_S8,
Max::get().player_hp(), 0.1f);
ImGui::DragScalar("More health##PlayerMoreHealth", ImGuiDataType_S8,
Expand Down Expand Up @@ -1506,6 +1662,8 @@ bool UI::Keys() {
options["cheat_godmode"].value ^= true;
else if (ImGui::IsKeyChordPressed(keys["toggle_damage"]))
options["cheat_damage"].value ^= true;
else if (ImGui::IsKeyChordPressed(keys["toggle_stats"]))
options["cheat_stats"].value ^= true;
else if (ImGui::IsKeyChordPressed(keys["toggle_darkness"]))
options["cheat_darkness"].value ^= true;
else if (ImGui::IsKeyChordPressed(keys["toggle_lights"]))
Expand Down Expand Up @@ -1671,6 +1829,15 @@ void UI::Cheats() {
} else {
recover_mem("cheat_water");
}

if (options["cheat_stats"].value) {
if (*Max::get().player_hp() < 12)
*Max::get().player_hp() = 12;
*(Max::get().player_hp() + 1) = 4;
*Max::get().keys() = 9;
*(Max::get().keys() + 1) = 9;
*(Max::get().keys() + 2) = 255;
}
}

void UI::Windows() {
Expand Down
6 changes: 5 additions & 1 deletion ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ class UI {
{"toggle_ui", ImGuiKey_F10},
{"toggle_noclip", ImGuiMod_Ctrl | ImGuiKey_F},
{"toggle_godmode", ImGuiMod_Ctrl | ImGuiKey_G},
{"toggle_damage", ImGuiMod_Ctrl | ImGuiKey_D},
{"toggle_damage", ImGuiMod_Shift | ImGuiKey_G},
{"toggle_stats", ImGuiMod_Alt | ImGuiKey_G},
{"toggle_darkness", ImGuiMod_Ctrl | ImGuiKey_L},
{"toggle_lights", ImGuiMod_Shift | ImGuiKey_L},
{"toggle_palette", ImGuiMod_Alt | ImGuiKey_L},
Expand Down Expand Up @@ -151,6 +152,9 @@ class UI {
"time."}},
{"cheat_water",
{false, "Hide water", "Makes water see-through but still functional."}},
{"cheat_stats",
{false, "Max out consumables", "Keeps your consumables stacked.",
"toggle_stats"}},

{"input_block",
{true, "Block game input on UI input",
Expand Down

0 comments on commit 2cad776

Please sign in to comment.