diff --git a/game_controller.c b/game_controller.c index 9c13c59..e34c823 100644 --- a/game_controller.c +++ b/game_controller.c @@ -1136,6 +1136,42 @@ void show_text() { "mov [0x1FEA094],eax;"); } +// game begin +typedef void (*HandleGameBeginEvent)(void); + +HandleGameBeginEvent handle_game_begin_event; + +void game_begin_hook_handler() { + // backup registers + asm ("push eax;"); + asm ("push ebx;"); + asm ("push ecx;"); + asm ("push edx;"); + asm ("push esi;"); + + handle_game_begin_event(); + // restore registers + asm ("pop esi;"); + asm ("pop edx;"); + asm ("pop ecx;"); + asm ("pop ebx;"); + asm ("pop eax;"); + + // back to normal path 1 + asm ("leave;"); + + // execute stole code + asm ("mov eax,0x0000190;"); + + // back to normal path 2 + asm ("jmp 0x04F6CFD;"); +} + +void execute_callback_on_game_begin(HandleGameBeginEvent function) { + handle_game_begin_event = function; + hook_at(0x04F6CF8, (void*)game_begin_hook_handler); +} + void free_memory(char *ptr) { free(ptr); diff --git a/strongmod/api/game.py b/strongmod/api/game.py index c1424c2..f3143fd 100644 --- a/strongmod/api/game.py +++ b/strongmod/api/game.py @@ -1,11 +1,14 @@ from common.singleton import Singleton -from internal.game_controller import set_on_tick_listener, is_game_created, get_resolution, disable_bot, show_message +from internal.game_controller import set_on_tick_listener, is_game_created, get_resolution, disable_bot, show_message, \ + set_on_game_begin_listener from api.lord import Lord, LordDoesNotExistException class Game(metaclass=Singleton): def __init__(self): self.tick_listeners = [] + set_on_game_begin_listener(self.publish_game_begin) + self.game_begin_listeners = [] set_on_tick_listener(self.publish) self.replaced_default_bots = {} self.set_on_tick_listener(self.tick_replaced_default_bots) @@ -70,3 +73,28 @@ def show_message(self, title, message): game.show_message("hello,", "world") """ show_message(title, message) + + def publish_game_begin(self): + for game_begin_listener in self.game_begin_listeners: + game_begin_listener() + + def register_game_begin_listener(self, game_begin_listener): + """ + Register a listener to be notified when the game begins. + + The registered listener will be called when the game begins, such as when + a saved game is loaded or when the game editor starts, etc. + + :param game_begin_listener: A callable object, such as a + function or method, to be notified when the game begins. + :type game_begin_listener: callable + + :Example: + game = Game() + + def game_begin_listener(): + game.show_message("hello,", "world") + + game.register_game_begin_listener(game_begin_listener) + """ + self.game_begin_listeners.append(game_begin_listener) diff --git a/strongmod/internal/game_controller.py b/strongmod/internal/game_controller.py index e5a5128..b69f11d 100644 --- a/strongmod/internal/game_controller.py +++ b/strongmod/internal/game_controller.py @@ -417,3 +417,18 @@ def get_all_buildings(): _game_controller.show_text.restype = ctypes.c_void_p show_text = _game_controller.show_text + + +class GameBeginListener: + listener = None + + +@ctypes.CFUNCTYPE(ctypes.c_void_p) +def handle_game_begin_event(): + GameBeginListener.listener() + + +def set_on_game_begin_listener(listener): + GameBeginListener.listener = listener + + _game_controller.execute_callback_on_game_begin(handle_game_begin_event)