Support server changing, locking, and reverting lighting mode

This commit is contained in:
Goodlyay 2024-05-18 17:32:26 -07:00
parent 64c4582b01
commit f4aaced448
7 changed files with 100 additions and 19 deletions

View File

@ -82,6 +82,7 @@ void Event_UnregisterAll(void) {
WorldEvents.Loading.Count = 0;
WorldEvents.MapLoaded.Count = 0;
WorldEvents.EnvVarChanged.Count = 0;
WorldEvents.LightingModeChanged.Count = 0;
ChatEvents.FontChanged.Count = 0;
ChatEvents.ChatReceived.Count = 0;

View File

@ -162,10 +162,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_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 */
} WorldEvents;
CC_VAR extern struct _ChatEventsList {

View File

@ -11,10 +11,14 @@
#include "Chat.h"
#include "ExtMath.h"
#include "Options.h"
#include "Builder.h"
const char* const LightingMode_Names[LIGHTING_MODE_COUNT] = { "Classic", "Fancy" };
cc_uint8 Lighting_Mode;
cc_bool Lighting_ModeLockedByServer;
cc_bool Lighting_ModeSetByServer;
cc_uint8 Lighting_ModeCached;
struct _Lighting Lighting;
#define Lighting_Pack(x, z) ((x) + World.Width * (z))
@ -414,7 +418,7 @@ static void ClassicLighting_SetActive(void) {
/*########################################################################################################################*
*---------------------------------------------------Lighting component----------------------------------------------------*
*#########################################################################################################################*/
void Lighting_ApplyActive(void) {
static void Lighting_ApplyActive(void) {
if (Lighting_Mode != LIGHTING_MODE_CLASSIC) {
FancyLighting_SetActive();
} else {
@ -422,18 +426,33 @@ void Lighting_ApplyActive(void) {
}
}
void Lighting_SwitchActive(void) {
static void Lighting_SwitchActive(void) {
Lighting.FreeState();
Lighting_ApplyActive();
Lighting.AllocState();
}
static void Lighting_HandleModeChanged(void* obj, int locked) {
Builder_ApplyActive();
if (World.Loaded) {
Lighting_SwitchActive();
MapRenderer_Refresh();
} else {
Lighting_ApplyActive();
}
}
static void OnInit(void) {
Lighting_Mode = Options_GetEnum(OPT_LIGHTING_MODE, LIGHTING_MODE_CLASSIC, LightingMode_Names, LIGHTING_MODE_COUNT);
Lighting_ModeLockedByServer = false;
Lighting_ModeSetByServer = false;
Lighting_ModeCached = Lighting_Mode;
FancyLighting_OnInit();
Lighting_ApplyActive();
Event_Register_(&WorldEvents.LightingModeChanged, NULL, Lighting_HandleModeChanged);
}
static void OnReset(void) { Lighting.FreeState(); }
static void OnNewMapLoaded(void) { Lighting.AllocState(); }

View File

@ -17,6 +17,12 @@ enum LightingMode {
extern const char* const LightingMode_Names[LIGHTING_MODE_COUNT];
extern cc_uint8 Lighting_Mode;
extern cc_bool Lighting_ModeLockedByServer;
/* True if the current lighting mode has been set by the server instead of the client */
extern cc_bool Lighting_ModeSetByServer;
/* The lighting mode that was set by the client before being set by the server */
extern cc_uint8 Lighting_ModeCached;
/* How much ambient occlusion to apply in fancy lighting where 1.0f = none and 0.0f = maximum*/
#define FANCY_AO 0.5F
@ -65,8 +71,6 @@ CC_VAR extern struct _Lighting {
PackedCol (*Color_ZSide_Fast)(int x, int y, int z);
} Lighting;
void Lighting_SwitchActive(void);
void Lighting_ApplyActive(void);
void FancyLighting_SetActive(void);
void FancyLighting_OnInit(void);

View File

@ -562,7 +562,7 @@ static void PauseScreen_Init(void* screen) {
if (Server.IsSinglePlayer) return;
s->btns[3].flags = WIDGET_FLAG_DISABLED;
s->btns[5].flags = WIDGET_FLAG_DISABLED;
s->btns[4].flags = WIDGET_FLAG_DISABLED;
}
static void PauseScreen_Free(void* screen) {
@ -2389,7 +2389,7 @@ static struct MenuOptionsScreen {
Screen_Body
const char* descriptions[MENUOPTS_MAX_OPTS + 1];
struct ButtonWidget* activeBtn;
InitMenuOptions DoInit, DoRecreateExtra, OnHacksChanged;
InitMenuOptions DoInit, DoRecreateExtra, OnHacksChanged, OnLightingModeServerChanged;
int numButtons;
struct FontDesc titleFont, textFont;
struct TextGroupWidget extHelp;
@ -2584,6 +2584,14 @@ static void MenuOptionsScreen_OnHacksChanged(void* screen) {
if (s->OnHacksChanged) s->OnHacksChanged(s);
s->dirty = true;
}
static void MenuOptionsScreen_OnLightingModeServerChanged(void* screen, int fromServer) {
struct MenuOptionsScreen* s = (struct MenuOptionsScreen*)screen;
/* This event only actually matters if it's from the server */
if (fromServer) {
if (s->OnLightingModeServerChanged) s->OnLightingModeServerChanged(s);
s->dirty = true;
}
}
static void MenuOptionsScreen_Init(void* screen) {
struct MenuOptionsScreen* s = (struct MenuOptionsScreen*)screen;
@ -2606,6 +2614,7 @@ static void MenuOptionsScreen_Init(void* screen) {
TextGroupWidget_Create(&s->extHelp, 5, s->extHelpTextures, MenuOptionsScreen_GetDesc);
s->extHelp.lines = 0;
Event_Register_(&UserEvents.HackPermsChanged, screen, MenuOptionsScreen_OnHacksChanged);
Event_Register_(&WorldEvents.LightingModeChanged, screen, MenuOptionsScreen_OnLightingModeServerChanged);
s->maxVertices = Screen_CalcDefaultMaxVertices(s);
}
@ -2629,6 +2638,7 @@ static void MenuOptionsScreen_Render(void* screen, float delta) {
static void MenuOptionsScreen_Free(void* screen) {
struct MenuOptionsScreen* s = (struct MenuOptionsScreen*)screen;
Event_Unregister_(&UserEvents.HackPermsChanged, screen, MenuOptionsScreen_OnHacksChanged);
Event_Unregister_(&WorldEvents.LightingModeChanged, screen, MenuOptionsScreen_OnLightingModeServerChanged);
Gui_RemoveCore((struct Screen*)&MenuInputOverlay);
}
@ -2868,13 +2878,22 @@ void EnvSettingsScreen_Show(void) {
/*########################################################################################################################*
*--------------------------------------------------GraphicsOptionsScreen--------------------------------------------------*
*#########################################################################################################################*/
static void GraphicsOptionsScreen_CheckLightingModeAllowed(struct MenuOptionsScreen* s) {
struct Widget** widgets = s->widgets;
cc_bool disabled = Lighting_ModeLockedByServer;
struct ButtonWidget* btn = (struct ButtonWidget*)widgets[4];
MenuOptionsScreen_Update(s, btn);
Widget_SetDisabled(widgets[4], disabled);
MenuInputOverlay_CheckStillValid(s);
}
static void GraphicsOptionsScreen_GetViewDist(cc_string* v) { String_AppendInt(v, Game_ViewDistance); }
static void GraphicsOptionsScreen_SetViewDist(const cc_string* v) { Game_UserSetViewDistance(Menu_Int(v)); }
static void GraphicsOptionsScreen_GetSmooth(cc_string* v) { Menu_GetBool(v, Builder_SmoothLighting); }
static void GraphicsOptionsScreen_SetSmooth(const cc_string* v) {
Builder_SmoothLighting = Menu_SetBool(v, OPT_SMOOTH_LIGHTING);
Lighting_ApplyActive();
Builder_ApplyActive();
MapRenderer_Refresh();
}
@ -2882,10 +2901,9 @@ static void GraphicsOptionsScreen_GetLighting(cc_string* v) { String_AppendConst
static void GraphicsOptionsScreen_SetLighting(const cc_string* v) {
Lighting_Mode = Utils_ParseEnum(v, 0, LightingMode_Names, LIGHTING_MODE_COUNT);
Options_Set(OPT_LIGHTING_MODE, v);
Lighting_SwitchActive();
Builder_ApplyActive();
MapRenderer_Refresh();
Lighting_ModeSetByServer = false;
/* Call with 0 to indicate clientside menu change */
Event_RaiseInt(&WorldEvents.LightingModeChanged, 0);
}
static void GraphicsOptionsScreen_GetCamera(cc_string* v) { Menu_GetBool(v, Camera.Smooth); }
@ -2943,7 +2961,11 @@ static void GraphicsOptionsScreen_InitWidgets(struct MenuOptionsScreen* s) {
{ 1, 50, "Anaglyph 3D", MenuOptionsScreen_Bool,
ClassicOptionsScreen_GetAnaglyph, ClassicOptionsScreen_SetAnaglyph }
};
s->OnLightingModeServerChanged = GraphicsOptionsScreen_CheckLightingModeAllowed;
MenuOptionsScreen_AddButtons(s, buttons, Array_Elems(buttons), Menu_SwitchOptions);
GraphicsOptionsScreen_CheckLightingModeAllowed(s);
s->descriptions[0] = "&eChange the smoothness of the smooth camera.";
s->descriptions[1] = \
@ -2955,9 +2977,11 @@ static void GraphicsOptionsScreen_InitWidgets(struct MenuOptionsScreen* s) {
"&eSmooth lighting smooths lighting and adds a minor glow to bright blocks.\n" \
"&cNote: &eThis setting may reduce performance.";
s->descriptions[4] = \
"&eClassic: &fTwo levels of light, sun and shadow. Good for performance.\n" \
"&eFancy: &fAllows bright blocks to cast a much wider range of light.\n" \
"&cNote: &eFancy will reduce performance and increase memory usage.";
"&eClassic: &fTwo levels of light, sun and shadow.\n" \
" Good for performance.\n" \
"&eFancy: &fBright blocks cast a much wider range of light\n" \
" May heavily reduce performance.\n" \
"&cNote: &eIn multiplayer, this option may be changed or locked by the server.";
s->descriptions[6] = \
"&eNone: &fNo names of players are drawn.\n" \
"&eHovered: &fName of the targeted player is drawn see-through.\n" \

View File

@ -88,6 +88,7 @@ static struct CpeExt
customModels_Ext = { "CustomModels", 2 },
pluginMessages_Ext = { "PluginMessages", 1 },
extTeleport_Ext = { "ExtEntityTeleport", 1 },
lightingMode_Ext = { "LightingMode", 1 },
extTextures_Ext = { "ExtendedTextures", 1 },
extBlocks_Ext = { "ExtendedBlocks", 1 };
@ -97,7 +98,7 @@ static struct CpeExt* cpe_clientExtensions[] = {
&messageTypes_Ext, &hackControl_Ext, &playerClick_Ext, &fullCP437_Ext, &longerMessages_Ext, &blockDefs_Ext,
&blockDefsExt_Ext, &bulkBlockUpdate_Ext, &textColors_Ext, &envMapAspect_Ext, &entityProperty_Ext, &extEntityPos_Ext,
&twoWayPing_Ext, &invOrder_Ext, &instantMOTD_Ext, &fastMap_Ext, &setHotbar_Ext, &setSpawnpoint_Ext, &velControl_Ext,
&customParticles_Ext, &pluginMessages_Ext, &extTeleport_Ext,
&customParticles_Ext, &pluginMessages_Ext, &extTeleport_Ext, &lightingMode_Ext,
#ifdef CUSTOM_MODELS
&customModels_Ext,
#endif
@ -1530,6 +1531,35 @@ static void CPE_ExtEntityTeleport(cc_uint8* data) {
Classic_ReadAbsoluteLocation(data, id, flags);
}
static void CPE_LightingMode(cc_uint8* data) {
cc_uint8 mode = *data++;
cc_uint8 lockedByte = *data++;
cc_bool locked = lockedByte > 0 ? true : false;
if (mode == 0) {
if (!Lighting_ModeSetByServer) return;
/* locked is ignored with mode 0 and always set to false */
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);
return;
}
/* Convert from Network mode (0 = no change, 1 = classic, 2 = fancy) to client mode (0 = classic, 1 = fancy) */
mode--;
if (mode >= LIGHTING_MODE_COUNT) return;
if (!Lighting_ModeSetByServer) Lighting_ModeCached = Lighting_Mode;
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);
}
static void CPE_Reset(void) {
cpe_serverExtensionsCount = 0; cpe_pingTicks = 0;
CPEExtensions_Reset();
@ -1572,6 +1602,7 @@ static void CPE_Reset(void) {
Net_Set(OPCODE_SPAWN_EFFECT, CPE_SpawnEffect, 26);
Net_Set(OPCODE_PLUGIN_MESSAGE, CPE_PluginMessage, 66);
Net_Set(OPCODE_ENTITY_TELEPORT_EXT, CPE_ExtEntityTeleport, 11);
Net_Set(OPCODE_LIGHTING_MODE, CPE_LightingMode, 3);
}
static cc_uint8* CPE_Tick(cc_uint8* data) {

View File

@ -37,6 +37,7 @@ enum OPCODE_ {
OPCODE_DEFINE_EFFECT, OPCODE_SPAWN_EFFECT,
OPCODE_DEFINE_MODEL, OPCODE_DEFINE_MODEL_PART, OPCODE_UNDEFINE_MODEL,
OPCODE_PLUGIN_MESSAGE, OPCODE_ENTITY_TELEPORT_EXT,
OPCODE_LIGHTING_MODE,
OPCODE_COUNT
};