44#include "aoc-builtin-rms.h"
55#include "hook.h"
66
7- #define RMS_STANDARD 0
8- #define RMS_REALWORLD 1
9-
107#define TERRAIN_TEXTURE_BASE 15000
118#define TERRAIN_TEXTURE_MAX 15050
129
@@ -74,6 +71,9 @@ typedef int __thiscall (*fn_ai_define_const)(void*, char*, int);
7471static const size_t offs_vtbl_map_generate = 0x638114 ;
7572static const size_t offs_map_generate = 0x45EE10 ;
7673static const size_t offs_load_scx = 0x40DF00 ;
74+ static const size_t offs_vtbl_launch_game = 0x63E0B0 ;
75+ static const size_t offs_launch_game = 0x4FF390 ;
76+ typedef void __thiscall (* fn_launch_game )(void * , int , int , int , int , int , int , int , int , int );
7777typedef int __thiscall (* fn_map_generate )(void * , int , int , char * , void * , int );
7878typedef int __thiscall (* fn_load_scx )(void * , char * , int , void * );
7979
@@ -91,6 +91,7 @@ static fn_text_get_value aoc_text_get_value = 0;
9191static fn_text_set_rollover_id aoc_text_set_rollover_id = 0 ;
9292static fn_ai_define_symbol aoc_ai_define_symbol = 0 ;
9393static fn_ai_define_const aoc_ai_define_const = 0 ;
94+ static fn_launch_game aoc_launch_game = 0 ;
9495static fn_map_generate aoc_map_generate = 0 ;
9596static fn_load_scx aoc_load_scx = 0 ;
9697static fn_texture_create aoc_texture_create = 0 ;
@@ -101,6 +102,11 @@ static int get_map_type() {
101102 return * (int * )(base_offset + offs_map_type );
102103}
103104
105+ static void set_map_type (int map_type ) {
106+ int base_offset = * (int * )offs_game_instance ;
107+ * (int * )(base_offset + offs_map_type ) = map_type ;
108+ }
109+
104110static void * get_world () {
105111 int base_offset = * (int * )offs_game_instance ;
106112 return * (void * * )(base_offset + offs_world );
@@ -120,20 +126,20 @@ static void __thiscall dropdown_add_line_hook(void* dd, int label, int value) {
120126 return ;
121127 }
122128
123- int additional_type = -1 ;
129+ custom_map_type_t additional_type = None ;
124130 if (is_last_map_dropdown_entry (label , value ))
125- additional_type = RMS_STANDARD ;
131+ additional_type = Standard ;
126132 if (is_last_real_world_dropdown_entry (label , value ))
127- additional_type = RMS_REALWORLD ;
133+ additional_type = RealWorld ;
128134
129- if (additional_type != -1 ) {
135+ if (additional_type != None ) {
130136 dbg_print ("called hooked dropdown_add_line %p %p, %d %d\n" , dd , text_panel , label , value );
131137 }
132138
133139 // Original
134140 aoc_text_add_line (text_panel , label , value );
135141
136- if (additional_type != -1 ) {
142+ if (additional_type != None ) {
137143 for (int i = 0 ; i < num_custom_maps ; i ++ ) {
138144 if (custom_maps [i ].type != additional_type ) continue ;
139145 aoc_text_add_line (text_panel ,
@@ -190,6 +196,41 @@ static void apply_terrain_overrides(terrain_overrides_t* overrides) {
190196 }
191197}
192198
199+ static int builtin_real_world_map_ids [] = { 34 , 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 };
200+ static int num_builtin_real_world_maps = sizeof (builtin_real_world_map_ids ) / sizeof (int );
201+ static int count_real_world_maps () {
202+ int result = num_builtin_real_world_maps ;
203+ for (int i = 0 ; i < num_custom_maps ; i ++ ) {
204+ if (custom_maps [i ].type == RealWorld ) {
205+ result ++ ;
206+ }
207+ }
208+ return result ;
209+ }
210+
211+ // only has this many "parameters" in userpatch, i think
212+ // maybe can tweak this depending on the game version
213+ 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 ) {
214+ if (get_map_type () == 47 ) {
215+ dbg_print ("[aoc-builtin-rms] picking full random real world map...\n" );
216+ int max = count_real_world_maps ();
217+ int pick = (rand () % max );
218+ if (pick < num_builtin_real_world_maps ) {
219+ set_map_type (builtin_real_world_map_ids [pick ]);
220+ } else {
221+ pick -= num_builtin_real_world_maps ;
222+ for (int i = 0 ; i < num_custom_maps ; i ++ ) {
223+ if (custom_maps [i ].type == RealWorld && -- pick == 0 ) {
224+ set_map_type (custom_maps [i ].id );
225+ break ;
226+ }
227+ }
228+ }
229+ }
230+
231+ return aoc_launch_game (screen , a , b , c , d , e , f , g , h , i );
232+ }
233+
193234static void * current_game_info ;
194235static void __thiscall map_generate_hook (void * map , int size_x , int size_y , char * name , void * game_info , int num_players ) {
195236 dbg_print ("called hooked map_generate %s %p\n" , name , game_info );
@@ -291,7 +332,9 @@ void aoc_builtin_rms_init(custom_map_t* new_custom_maps, size_t new_num_custom_m
291332 /* Stuff to make real world maps work */
292333 aoc_map_generate = (fn_map_generate ) offs_map_generate ;
293334 aoc_load_scx = (fn_load_scx ) offs_load_scx ;
335+ aoc_launch_game = (fn_launch_game ) offs_launch_game ;
294336 hooks [h ++ ] = install_vtblhook ((void * ) offs_vtbl_map_generate , map_generate_hook );
337+ hooks [h ++ ] = install_vtblhook ((void * ) offs_vtbl_launch_game , launch_game_hook );
295338 hooks [h ] = NULL ;
296339}
297340
0 commit comments