@@ -73,6 +73,9 @@ typedef int __thiscall (*fn_ai_define_const)(void*, char*, int);
7373static const size_t offs_vtbl_map_generate = 0x638114 ;
7474static const size_t offs_map_generate = 0x45EE10 ;
7575static const size_t offs_load_scx = 0x40DF00 ;
76+ static const size_t offs_vtbl_launch_game = 0x63E0B0 ;
77+ static const size_t offs_launch_game = 0x4FF390 ;
78+ typedef void __thiscall (* fn_launch_game )(void * , int , int , int , int , int , int , int , int , int );
7679typedef int __thiscall (* fn_map_generate )(void * , int , int , char * , void * , int );
7780typedef int __thiscall (* fn_load_scx )(void * , char * , int , void * );
7881
@@ -90,6 +93,7 @@ static fn_text_get_value aoc_text_get_value = 0;
9093static fn_text_set_rollover_id aoc_text_set_rollover_id = 0 ;
9194static fn_ai_define_symbol aoc_ai_define_symbol = 0 ;
9295static fn_ai_define_const aoc_ai_define_const = 0 ;
96+ static fn_launch_game aoc_launch_game = 0 ;
9397static fn_map_generate aoc_map_generate = 0 ;
9498static fn_load_scx aoc_load_scx = 0 ;
9599static fn_texture_create aoc_texture_create = 0 ;
@@ -100,6 +104,11 @@ static int get_map_type() {
100104 return * (int * )(base_offset + offs_map_type );
101105}
102106
107+ static void set_map_type (int map_type ) {
108+ int base_offset = * (int * )offs_game_instance ;
109+ * (int * )(base_offset + offs_map_type ) = map_type ;
110+ }
111+
103112static void * get_world () {
104113 int base_offset = * (int * )offs_game_instance ;
105114 return * (void * * )(base_offset + offs_world );
@@ -189,6 +198,41 @@ static void apply_terrain_overrides(terrain_overrides_t* overrides) {
189198 }
190199}
191200
201+ static int builtin_real_world_map_ids [] = { 34 , 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 };
202+ static int num_builtin_real_world_maps = sizeof (builtin_real_world_map_ids ) / sizeof (int );
203+ static int count_real_world_maps () {
204+ int result = num_builtin_real_world_maps ;
205+ for (int i = 0 ; i < num_custom_maps ; i ++ ) {
206+ if (custom_maps [i ].type == RMS_REALWORLD ) {
207+ result ++ ;
208+ }
209+ }
210+ return result ;
211+ }
212+
213+ // only has this many "parameters" in userpatch, i think
214+ // maybe can tweak this depending on the game version
215+ static void __thiscall launch_game_hook (void * screen , int a , int b , int c , int d , int e , int f , int g , int h , int i ) {
216+ if (get_map_type () == 47 ) {
217+ debug ("[aoc-builtin-rms] picking full random real world map...\n" );
218+ int max = count_real_world_maps ();
219+ int pick = (rand () % max );
220+ if (pick < num_builtin_real_world_maps ) {
221+ set_map_type (builtin_real_world_map_ids [pick ]);
222+ } else {
223+ pick -= num_builtin_real_world_maps ;
224+ for (int i = 0 ; i < num_custom_maps ; i ++ ) {
225+ if (custom_maps [i ].type == RMS_REALWORLD && -- pick == 0 ) {
226+ set_map_type (custom_maps [i ].id );
227+ break ;
228+ }
229+ }
230+ }
231+ }
232+
233+ return aoc_launch_game (screen , a , b , c , d , e , f , g , h , i );
234+ }
235+
192236static void * current_game_info ;
193237static void __thiscall map_generate_hook (void * map , int size_x , int size_y , char * name , void * game_info , int num_players ) {
194238 debug ("[aoc-builtin-rms] called hooked map_generate %s %p\n" , name , game_info );
@@ -345,7 +389,9 @@ void aoc_builtin_rms_init(custom_map_t* new_custom_maps, size_t new_num_custom_m
345389 /* Stuff to make real world maps work */
346390 aoc_map_generate = (fn_map_generate ) offs_map_generate ;
347391 aoc_load_scx = (fn_load_scx ) offs_load_scx ;
392+ aoc_launch_game = (fn_launch_game ) offs_launch_game ;
348393 install_vtblhook ((void * ) offs_vtbl_map_generate , map_generate_hook );
394+ install_vtblhook ((void * ) offs_vtbl_launch_game , launch_game_hook );
349395}
350396
351397void deinit () {
0 commit comments