2021-01-27 21:26:19 +00:00
|
|
|
#include <libreborn/libreborn.h>
|
2020-12-02 23:18:49 +00:00
|
|
|
|
|
|
|
#include "game_mode.h"
|
|
|
|
|
|
|
|
#include "../minecraft.h"
|
|
|
|
|
|
|
|
// Get Minecraft From Screen
|
|
|
|
static unsigned char *get_minecraft_from_screen(unsigned char *screen) {
|
2020-12-18 03:22:56 +00:00
|
|
|
return *(unsigned char **) (screen + Screen_minecraft_property_offset);
|
2020-12-02 23:18:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Redirect Create World Button To SimpleLevelChooseScreen
|
|
|
|
#define WORLD_NAME "world"
|
|
|
|
static void SelectWorldScreen_tick_injection(unsigned char *screen) {
|
2020-12-18 03:22:56 +00:00
|
|
|
bool create_world = *(bool *) (screen + SelectWorldScreen_should_create_world_property_offset);
|
2020-12-02 23:18:49 +00:00
|
|
|
if (create_world) {
|
|
|
|
// Get New World Name
|
2020-12-05 01:54:29 +00:00
|
|
|
std::string new_name = (*SelectWorldScreen_getUniqueLevelName)(screen, WORLD_NAME);
|
2020-12-02 23:18:49 +00:00
|
|
|
// Create SimpleLevelChooseScreen
|
|
|
|
unsigned char *new_screen = (unsigned char *) ::operator new(SIMPLE_LEVEL_CHOOSE_SCREEN_SIZE);
|
|
|
|
(*SimpleChooseLevelScreen)(new_screen, new_name);
|
|
|
|
// Set Screen
|
|
|
|
unsigned char *minecraft = get_minecraft_from_screen(screen);
|
|
|
|
(*Minecraft_setScreen)(minecraft, new_screen);
|
|
|
|
// Finish
|
2020-12-18 03:22:56 +00:00
|
|
|
*(bool *) (screen + SelectWorldScreen_world_created_property_offset) = true;
|
2020-12-02 23:18:49 +00:00
|
|
|
} else {
|
|
|
|
(*SelectWorldScreen_tick)(screen);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
static void Touch_SelectWorldScreen_tick_injection(unsigned char *screen) {
|
2020-12-18 03:22:56 +00:00
|
|
|
bool create_world = *(bool *) (screen + Touch_SelectWorldScreen_should_create_world_property_offset);
|
2020-12-02 23:18:49 +00:00
|
|
|
if (create_world) {
|
|
|
|
// Get New World Name
|
2020-12-05 01:54:29 +00:00
|
|
|
std::string new_name = (*Touch_SelectWorldScreen_getUniqueLevelName)(screen, WORLD_NAME);
|
2020-12-02 23:18:49 +00:00
|
|
|
// Create SimpleLevelChooseScreen
|
|
|
|
unsigned char *new_screen = (unsigned char *) ::operator new(SIMPLE_LEVEL_CHOOSE_SCREEN_SIZE);
|
|
|
|
(*SimpleChooseLevelScreen)(new_screen, new_name);
|
|
|
|
// Set Screen
|
|
|
|
unsigned char *minecraft = get_minecraft_from_screen(screen);
|
|
|
|
(*Minecraft_setScreen)(minecraft, new_screen);
|
|
|
|
// Finish
|
2020-12-18 03:22:56 +00:00
|
|
|
*(bool *) (screen + Touch_SelectWorldScreen_world_created_property_offset) = true;
|
2020-12-02 23:18:49 +00:00
|
|
|
} else {
|
|
|
|
(*Touch_SelectWorldScreen_tick)(screen);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void init_game_mode_cpp() {
|
|
|
|
// Hijack Create World Button
|
|
|
|
patch_address(SelectWorldScreen_tick_vtable_addr, (void *) SelectWorldScreen_tick_injection);
|
|
|
|
patch_address(Touch_SelectWorldScreen_tick_vtable_addr, (void *) Touch_SelectWorldScreen_tick_injection);
|
|
|
|
// Make The SimpleChooseLevelScreen Back Button Go To SelectWorldScreen Instead Of StartMenuScreen
|
|
|
|
unsigned char simple_choose_level_screen_back_button_patch[4] = {0x05, 0x10, 0xa0, 0xe3};
|
|
|
|
patch((void *) 0x31144, simple_choose_level_screen_back_button_patch);
|
|
|
|
}
|