diff --git a/src/Event.c b/src/Event.c index 66e04a4bc..c111543bd 100644 --- a/src/Event.c +++ b/src/Event.c @@ -192,3 +192,10 @@ void Event_RaisePluginMessage(struct Event_PluginMessage* handlers, cc_uint8 cha handlers->Handlers[i](handlers->Objs[i], channel, data); } } + +void Event_RaiseLightingMode(struct Event_LightingMode* handlers, cc_uint8 oldMode, cc_bool fromServer) { + int i; + for (i = 0; i < handlers->Count; i++) { + handlers->Handlers[i](handlers->Objs[i], oldMode, fromServer); + } +} \ No newline at end of file diff --git a/src/Event.h b/src/Event.h index 002b9ac84..59529128c 100644 --- a/src/Event.h +++ b/src/Event.h @@ -76,6 +76,12 @@ struct Event_PluginMessage { void* Objs[EVENT_MAX_CALLBACKS]; int Count; }; +typedef void (*Event_LightingMode_Callback)(void* obj, cc_uint8 oldMode, cc_bool fromServer); +struct Event_LightingMode { + Event_LightingMode_Callback Handlers[EVENT_MAX_CALLBACKS]; + void* Objs[EVENT_MAX_CALLBACKS]; int Count; +}; + /* Registers a callback function for the given event. */ /* NOTE: Trying to register a callback twice or over EVENT_MAX_CALLBACKS callbacks will terminate the game. */ CC_API void Event_Register(struct Event_Void* handlers, void* obj, Event_Void_Callback handler); @@ -111,6 +117,8 @@ void Event_RaiseRawMove(struct Event_RawMove* handlers, float xDelta, float yDel void Event_RaisePadAxis(struct Event_PadAxis* handlers, int port, int axis, float x, float y); /* Calls all registered callbacks for an event which has a channel and a 64 byte data argument. */ void Event_RaisePluginMessage(struct Event_PluginMessage* handlers, cc_uint8 channel, cc_uint8* data); +/* Calls all registered callbacks for an event called when the Lighting_LightingMode is changed */ +void Event_RaiseLightingMode(struct Event_LightingMode* handlers, cc_uint8 oldMode, cc_bool fromServer); void Event_UnregisterAll(void); /* NOTE: Event_UnregisterAll MUST be updated when events lists are changed */ @@ -162,11 +170,11 @@ CC_VAR extern struct _BlockEventsList { } BlockEvents; CC_VAR extern struct _WorldEventsList { - struct Event_Void NewMap; /* Player begins loading a new world */ - struct Event_Float Loading; /* Portion of world is decompressed/generated (Arg is progress from 0-1) */ - struct Event_Void MapLoaded; /* New world has finished loading, player can now interact with it */ - struct Event_Int EnvVarChanged; /* World environment variable changed by player/CPE/WoM config */ - struct Event_Int LightingModeChanged; /* Lighting mode changed. 0 or 1 indicates whether client or server is the cause of the change */ + struct Event_Void NewMap; /* Player begins loading a new world */ + struct Event_Float Loading; /* Portion of world is decompressed/generated (Arg is progress from 0-1) */ + struct Event_Void MapLoaded; /* New world has finished loading, player can now interact with it */ + struct Event_Int EnvVarChanged; /* World environment variable changed by player/CPE/WoM config */ + struct Event_LightingMode LightingModeChanged; /* Lighting mode changed. */ } WorldEvents; CC_VAR extern struct _ChatEventsList { diff --git a/src/Lighting.c b/src/Lighting.c index 690bd9d72..757670a2f 100644 --- a/src/Lighting.c +++ b/src/Lighting.c @@ -432,7 +432,8 @@ static void Lighting_SwitchActive(void) { Lighting.AllocState(); } -static void Lighting_HandleModeChanged(void* obj, int locked) { +static void Lighting_HandleModeChanged(void* obj, cc_uint8 oldMode, cc_bool fromServer) { + if (Lighting_Mode == oldMode) return; Builder_ApplyActive(); if (World.Loaded) { Lighting_SwitchActive(); diff --git a/src/Menus.c b/src/Menus.c index 4d1c2d9fd..b4af645a6 100644 --- a/src/Menus.c +++ b/src/Menus.c @@ -2584,7 +2584,7 @@ static void MenuOptionsScreen_OnHacksChanged(void* screen) { if (s->OnHacksChanged) s->OnHacksChanged(s); s->dirty = true; } -static void MenuOptionsScreen_OnLightingModeServerChanged(void* screen, int fromServer) { +static void MenuOptionsScreen_OnLightingModeServerChanged(void* screen, cc_uint8 oldMode, cc_bool fromServer) { struct MenuOptionsScreen* s = (struct MenuOptionsScreen*)screen; /* This event only actually matters if it's from the server */ if (fromServer) { @@ -2899,11 +2899,12 @@ static void GraphicsOptionsScreen_SetSmooth(const cc_string* v) { } static void GraphicsOptionsScreen_GetLighting(cc_string* v) { String_AppendConst(v, LightingMode_Names[Lighting_Mode]); } static void GraphicsOptionsScreen_SetLighting(const cc_string* v) { + cc_uint8 oldMode = Lighting_Mode; Lighting_Mode = Utils_ParseEnum(v, 0, LightingMode_Names, LIGHTING_MODE_COUNT); Options_Set(OPT_LIGHTING_MODE, v); Lighting_ModeSetByServer = false; - /* Call with 0 to indicate clientside menu change */ - Event_RaiseInt(&WorldEvents.LightingModeChanged, 0); + + Event_RaiseLightingMode(&WorldEvents.LightingModeChanged, oldMode, false); } static void GraphicsOptionsScreen_GetCamera(cc_string* v) { Menu_GetBool(v, Camera.Smooth); } diff --git a/src/Protocol.c b/src/Protocol.c index 917b0ddde..796aa9480 100644 --- a/src/Protocol.c +++ b/src/Protocol.c @@ -1535,6 +1535,7 @@ static void CPE_LightingMode(cc_uint8* data) { cc_uint8 mode = *data++; cc_uint8 lockedByte = *data++; cc_bool locked = lockedByte > 0 ? true : false; + cc_uint8 oldMode = Lighting_Mode; if (mode == 0) { if (!Lighting_ModeSetByServer) return; @@ -1542,9 +1543,8 @@ static void CPE_LightingMode(cc_uint8* data) { Lighting_ModeLockedByServer = false; Lighting_ModeSetByServer = false; Lighting_Mode = Lighting_ModeCached; - /* Call event even if mode is unchanged in case menu needs to be enabled/disabled */ - /* 1 indicates changed by server and thus menu needs to update */ - Event_RaiseInt(&WorldEvents.LightingModeChanged, 1); + + Event_RaiseLightingMode(&WorldEvents.LightingModeChanged, oldMode, true); return; } /* Convert from Network mode (0 = no change, 1 = classic, 2 = fancy) to client mode (0 = classic, 1 = fancy) */ @@ -1555,9 +1555,8 @@ static void CPE_LightingMode(cc_uint8* data) { Lighting_ModeLockedByServer = locked; Lighting_ModeSetByServer = true; Lighting_Mode = mode; - /* Call event even if mode is unchanged in case menu needs to be enabled/disabled */ - /* 1 indicates changed by server and thus menu needs to update */ - Event_RaiseInt(&WorldEvents.LightingModeChanged, 1); + + Event_RaiseLightingMode(&WorldEvents.LightingModeChanged, oldMode, true); } static void CPE_Reset(void) {