mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-25 13:51:43 +00:00
Merge branch 'cv-can-change' into 'next'
Add can_change for console variables See merge request STJr/SRB2!2196
This commit is contained in:
commit
3176abe2e4
4 changed files with 122 additions and 55 deletions
|
@ -1429,8 +1429,8 @@ void CV_RegisterVar(consvar_t *variable)
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
if ((variable->flags & CV_NOINIT) && !(variable->flags & CV_CALL))
|
if ((variable->flags & CV_NOINIT) && !(variable->flags & CV_CALL))
|
||||||
I_Error("variable %s has CV_NOINIT without CV_CALL\n", variable->name);
|
I_Error("variable %s has CV_NOINIT without CV_CALL\n", variable->name);
|
||||||
if ((variable->flags & CV_CALL) && !variable->func)
|
if ((variable->flags & CV_CALL) && !(variable->func || variable->can_change))
|
||||||
I_Error("variable %s has CV_CALL without a function\n", variable->name);
|
I_Error("variable %s has CV_CALL without any callbacks\n", variable->name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (variable->flags & CV_NOINIT)
|
if (variable->flags & CV_NOINIT)
|
||||||
|
@ -1496,12 +1496,35 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth)
|
||||||
boolean override = false;
|
boolean override = false;
|
||||||
INT32 overrideval = 0;
|
INT32 overrideval = 0;
|
||||||
|
|
||||||
// If we want messages informing us if cheats have been enabled or disabled,
|
// raise 'can change' code
|
||||||
// we need to rework the consvars a little bit. This call crashes the game
|
LUA_CVarChanged(var); // let consolelib know what cvar this is.
|
||||||
// on load because not all variables will be registered at that time.
|
if (var->flags & CV_CALL && var->can_change && !stealth)
|
||||||
/* boolean prevcheats = false;
|
{
|
||||||
if (var->flags & CV_CHEAT)
|
if (!var->can_change(valstr))
|
||||||
prevcheats = CV_CheatsEnabled(); */
|
{
|
||||||
|
// The callback refused the default value on register. How naughty...
|
||||||
|
// So we just use some fallback value.
|
||||||
|
if (var->string == NULL)
|
||||||
|
{
|
||||||
|
if (var->PossibleValue)
|
||||||
|
{
|
||||||
|
// Use PossibleValue
|
||||||
|
valstr = var->PossibleValue[0].strvalue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Else, use an empty string
|
||||||
|
valstr = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Callback returned false, and the game is not registering this variable,
|
||||||
|
// so we can return safely.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (var->PossibleValue)
|
if (var->PossibleValue)
|
||||||
{
|
{
|
||||||
|
@ -1663,16 +1686,6 @@ found:
|
||||||
}
|
}
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
// See the note above.
|
|
||||||
/* if (var->flags & CV_CHEAT)
|
|
||||||
{
|
|
||||||
boolean newcheats = CV_CheatsEnabled();
|
|
||||||
|
|
||||||
if (!prevcheats && newcheats)
|
|
||||||
CONS_Printf(M_GetText("Cheats have been enabled.\n"));
|
|
||||||
else if (prevcheats && !newcheats)
|
|
||||||
CONS_Printf(M_GetText("Cheats have been disabled.\n"));
|
|
||||||
} */
|
|
||||||
|
|
||||||
if (var->flags & CV_SHOWMODIFONETIME || var->flags & CV_SHOWMODIF)
|
if (var->flags & CV_SHOWMODIFONETIME || var->flags & CV_SHOWMODIF)
|
||||||
{
|
{
|
||||||
|
@ -1685,8 +1698,7 @@ finish:
|
||||||
}
|
}
|
||||||
var->flags |= CV_MODIFIED;
|
var->flags |= CV_MODIFIED;
|
||||||
// raise 'on change' code
|
// raise 'on change' code
|
||||||
LUA_CVarChanged(var); // let consolelib know what cvar this is.
|
if (var->flags & CV_CALL && var->func && !stealth)
|
||||||
if (var->flags & CV_CALL && !stealth)
|
|
||||||
var->func();
|
var->func();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -136,6 +136,7 @@ typedef struct consvar_s //NULL, NULL, 0, NULL, NULL |, 0, NULL, NULL, 0, 0, NUL
|
||||||
INT32 flags; // flags see cvflags_t above
|
INT32 flags; // flags see cvflags_t above
|
||||||
CV_PossibleValue_t *PossibleValue; // table of possible values
|
CV_PossibleValue_t *PossibleValue; // table of possible values
|
||||||
void (*func)(void); // called on change, if CV_CALL set
|
void (*func)(void); // called on change, if CV_CALL set
|
||||||
|
boolean (*can_change)(const char*); // called before change, if CV_CALL set
|
||||||
INT32 value; // for INT32 and fixed_t
|
INT32 value; // for INT32 and fixed_t
|
||||||
const char *string; // value in string
|
const char *string; // value in string
|
||||||
char *zstring; // Either NULL or same as string.
|
char *zstring; // Either NULL or same as string.
|
||||||
|
@ -158,6 +159,9 @@ typedef struct consvar_s //NULL, NULL, 0, NULL, NULL |, 0, NULL, NULL, 0, 0, NUL
|
||||||
|
|
||||||
/* name, defaultvalue, flags, PossibleValue, func */
|
/* name, defaultvalue, flags, PossibleValue, func */
|
||||||
#define CVAR_INIT( ... ) \
|
#define CVAR_INIT( ... ) \
|
||||||
|
{ __VA_ARGS__, NULL, 0, NULL, NULL, {0, {NULL}}, 0U, (char)0, NULL }
|
||||||
|
|
||||||
|
#define CVAR_INIT_WITH_CALLBACKS( ... ) \
|
||||||
{ __VA_ARGS__, 0, NULL, NULL, {0, {NULL}}, 0U, (char)0, NULL }
|
{ __VA_ARGS__, 0, NULL, NULL, {0, {NULL}}, 0U, (char)0, NULL }
|
||||||
|
|
||||||
#ifdef OLD22DEMOCOMPAT
|
#ifdef OLD22DEMOCOMPAT
|
||||||
|
|
|
@ -300,6 +300,30 @@ static void Lua_OnChange(void)
|
||||||
lua_remove(gL, 1); // remove LUA_GetErrorMessage
|
lua_remove(gL, 1); // remove LUA_GetErrorMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean Lua_CanChange(const char *valstr)
|
||||||
|
{
|
||||||
|
lua_pushcfunction(gL, LUA_GetErrorMessage);
|
||||||
|
lua_insert(gL, 1); // Because LUA_Call wants it at index 1.
|
||||||
|
|
||||||
|
// From CV_CanChange registry field, get the function for this cvar by name.
|
||||||
|
lua_getfield(gL, LUA_REGISTRYINDEX, "CV_CanChange");
|
||||||
|
I_Assert(lua_istable(gL, -1));
|
||||||
|
lua_pushlightuserdata(gL, this_cvar);
|
||||||
|
lua_rawget(gL, -2); // get function
|
||||||
|
|
||||||
|
LUA_RawPushUserdata(gL, this_cvar);
|
||||||
|
lua_pushstring(gL, valstr);
|
||||||
|
|
||||||
|
boolean result;
|
||||||
|
|
||||||
|
LUA_Call(gL, 2, 1, 1); // call function(cvar, valstr)
|
||||||
|
result = lua_toboolean(gL, -1);
|
||||||
|
lua_pop(gL, 1); // pop CV_CanChange table
|
||||||
|
lua_remove(gL, 1); // remove LUA_GetErrorMessage
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static int lib_cvRegisterVar(lua_State *L)
|
static int lib_cvRegisterVar(lua_State *L)
|
||||||
{
|
{
|
||||||
const char *k;
|
const char *k;
|
||||||
|
@ -458,6 +482,20 @@ static int lib_cvRegisterVar(lua_State *L)
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
cvar->func = Lua_OnChange;
|
cvar->func = Lua_OnChange;
|
||||||
}
|
}
|
||||||
|
else if (cvar->flags & CV_CALL && (k && fasticmp(k, "can_change")))
|
||||||
|
{
|
||||||
|
if (!lua_isfunction(L, 4))
|
||||||
|
{
|
||||||
|
TYPEERROR("func", LUA_TFUNCTION)
|
||||||
|
}
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, "CV_CanChange");
|
||||||
|
I_Assert(lua_istable(L, 5));
|
||||||
|
lua_pushlightuserdata(L, cvar);
|
||||||
|
lua_pushvalue(L, 4);
|
||||||
|
lua_rawset(L, 5);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
cvar->can_change = Lua_CanChange;
|
||||||
|
}
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,9 +517,9 @@ static int lib_cvRegisterVar(lua_State *L)
|
||||||
return luaL_error(L, M_GetText("Variable %s has CV_NOINIT without CV_CALL"), cvar->name);
|
return luaL_error(L, M_GetText("Variable %s has CV_NOINIT without CV_CALL"), cvar->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cvar->flags & CV_CALL) && !cvar->func)
|
if ((cvar->flags & CV_CALL) && !(cvar->func || cvar->can_change))
|
||||||
{
|
{
|
||||||
return luaL_error(L, M_GetText("Variable %s has CV_CALL without a function"), cvar->name);
|
return luaL_error(L, M_GetText("Variable %s has CV_CALL without any callbacks"), cvar->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
cvar->flags |= CV_ALLOWLUA;
|
cvar->flags |= CV_ALLOWLUA;
|
||||||
|
@ -672,6 +710,8 @@ int LUA_ConsoleLib(lua_State *L)
|
||||||
lua_setfield(L, LUA_REGISTRYINDEX, "CV_PossibleValue");
|
lua_setfield(L, LUA_REGISTRYINDEX, "CV_PossibleValue");
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
lua_setfield(L, LUA_REGISTRYINDEX, "CV_OnChange");
|
lua_setfield(L, LUA_REGISTRYINDEX, "CV_OnChange");
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_setfield(L, LUA_REGISTRYINDEX, "CV_CanChange");
|
||||||
|
|
||||||
// Push opaque CV_PossibleValue pointers
|
// Push opaque CV_PossibleValue pointers
|
||||||
// Because I don't care enough to bother.
|
// Because I don't care enough to bother.
|
||||||
|
|
|
@ -109,6 +109,9 @@ static void Color2_OnChange(void);
|
||||||
static void DummyConsvar_OnChange(void);
|
static void DummyConsvar_OnChange(void);
|
||||||
static void SoundTest_OnChange(void);
|
static void SoundTest_OnChange(void);
|
||||||
|
|
||||||
|
static boolean Skin_CanChange(const char *valstr);
|
||||||
|
static boolean Skin2_CanChange(const char *valstr);
|
||||||
|
|
||||||
#ifdef NETGAME_DEVMODE
|
#ifdef NETGAME_DEVMODE
|
||||||
static void Fishcake_OnChange(void);
|
static void Fishcake_OnChange(void);
|
||||||
#endif
|
#endif
|
||||||
|
@ -228,7 +231,6 @@ consvar_t cv_seenames = CVAR_INIT ("seenames", "Ally/Foe", CV_SAVE|CV_ALLOWLUA,
|
||||||
consvar_t cv_allowseenames = CVAR_INIT ("allowseenames", "Yes", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_YesNo, NULL);
|
consvar_t cv_allowseenames = CVAR_INIT ("allowseenames", "Yes", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_YesNo, NULL);
|
||||||
|
|
||||||
// names
|
// names
|
||||||
static char *lastskinnames[2];
|
|
||||||
consvar_t cv_playername = CVAR_INIT ("name", "Sonic", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name_OnChange);
|
consvar_t cv_playername = CVAR_INIT ("name", "Sonic", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name_OnChange);
|
||||||
consvar_t cv_playername2 = CVAR_INIT ("name2", "Tails", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name2_OnChange);
|
consvar_t cv_playername2 = CVAR_INIT ("name2", "Tails", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name2_OnChange);
|
||||||
// player colors
|
// player colors
|
||||||
|
@ -236,8 +238,8 @@ UINT16 lastgoodcolor = SKINCOLOR_BLUE, lastgoodcolor2 = SKINCOLOR_BLUE;
|
||||||
consvar_t cv_playercolor = CVAR_INIT ("color", "Blue", CV_CALL|CV_NOINIT|CV_ALLOWLUA, Color_cons_t, Color_OnChange);
|
consvar_t cv_playercolor = CVAR_INIT ("color", "Blue", CV_CALL|CV_NOINIT|CV_ALLOWLUA, Color_cons_t, Color_OnChange);
|
||||||
consvar_t cv_playercolor2 = CVAR_INIT ("color2", "Orange", CV_CALL|CV_NOINIT|CV_ALLOWLUA, Color_cons_t, Color2_OnChange);
|
consvar_t cv_playercolor2 = CVAR_INIT ("color2", "Orange", CV_CALL|CV_NOINIT|CV_ALLOWLUA, Color_cons_t, Color2_OnChange);
|
||||||
// player's skin, saved for commodity, when using a favorite skins wad..
|
// player's skin, saved for commodity, when using a favorite skins wad..
|
||||||
consvar_t cv_skin = CVAR_INIT ("skin", DEFAULTSKIN, CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Skin_OnChange);
|
consvar_t cv_skin = CVAR_INIT_WITH_CALLBACKS ("skin", DEFAULTSKIN, CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Skin_OnChange, Skin_CanChange);
|
||||||
consvar_t cv_skin2 = CVAR_INIT ("skin2", DEFAULTSKIN2, CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Skin2_OnChange);
|
consvar_t cv_skin2 = CVAR_INIT_WITH_CALLBACKS ("skin2", DEFAULTSKIN2, CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Skin2_OnChange, Skin2_CanChange);
|
||||||
|
|
||||||
// saved versions of the above six
|
// saved versions of the above six
|
||||||
consvar_t cv_defaultplayercolor = CVAR_INIT ("defaultcolor", "Blue", CV_SAVE, Color_cons_t, NULL);
|
consvar_t cv_defaultplayercolor = CVAR_INIT ("defaultcolor", "Blue", CV_SAVE, Color_cons_t, NULL);
|
||||||
|
@ -4792,6 +4794,41 @@ static void Name2_OnChange(void)
|
||||||
SendNameAndColor2();
|
SendNameAndColor2();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean Skin_CanChange(const char *valstr)
|
||||||
|
{
|
||||||
|
(void)valstr;
|
||||||
|
|
||||||
|
if (!Playing())
|
||||||
|
return true; // do whatever you want
|
||||||
|
|
||||||
|
if (!(multiplayer || netgame)) // In single player.
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (CanChangeSkin(consoleplayer) && !P_PlayerMoving(consoleplayer))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean Skin2_CanChange(const char *valstr)
|
||||||
|
{
|
||||||
|
(void)valstr;
|
||||||
|
|
||||||
|
if (!Playing() || !splitscreen)
|
||||||
|
return true; // do whatever you want
|
||||||
|
|
||||||
|
if (CanChangeSkin(secondarydisplayplayer) && !P_PlayerMoving(secondarydisplayplayer))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Sends a skin change for the console player, unless that player is moving.
|
/** Sends a skin change for the console player, unless that player is moving.
|
||||||
* \sa cv_skin, Skin2_OnChange, Color_OnChange
|
* \sa cv_skin, Skin2_OnChange, Color_OnChange
|
||||||
* \author Graue <graue@oceanbase.org>
|
* \author Graue <graue@oceanbase.org>
|
||||||
|
@ -4799,10 +4836,7 @@ static void Name2_OnChange(void)
|
||||||
static void Skin_OnChange(void)
|
static void Skin_OnChange(void)
|
||||||
{
|
{
|
||||||
if (!Playing())
|
if (!Playing())
|
||||||
return; // do whatever you want
|
return;
|
||||||
|
|
||||||
if (lastskinnames[0] == NULL)
|
|
||||||
lastskinnames[0] = Z_StrDup(cv_skin.string);
|
|
||||||
|
|
||||||
if (!(multiplayer || netgame)) // In single player.
|
if (!(multiplayer || netgame)) // In single player.
|
||||||
{
|
{
|
||||||
|
@ -4818,17 +4852,7 @@ static void Skin_OnChange(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CanChangeSkin(consoleplayer) && !P_PlayerMoving(consoleplayer))
|
SendNameAndColor();
|
||||||
{
|
|
||||||
SendNameAndColor();
|
|
||||||
Z_Free(lastskinnames[0]);
|
|
||||||
lastskinnames[0] = Z_StrDup(cv_skin.string);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
|
|
||||||
CV_StealthSet(&cv_skin, lastskinnames[0]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sends a skin change for the secondary splitscreen player, unless that
|
/** Sends a skin change for the secondary splitscreen player, unless that
|
||||||
|
@ -4839,22 +4863,9 @@ static void Skin_OnChange(void)
|
||||||
static void Skin2_OnChange(void)
|
static void Skin2_OnChange(void)
|
||||||
{
|
{
|
||||||
if (!Playing() || !splitscreen)
|
if (!Playing() || !splitscreen)
|
||||||
return; // do whatever you want
|
return;
|
||||||
|
|
||||||
if (lastskinnames[1] == NULL)
|
SendNameAndColor2();
|
||||||
lastskinnames[1] = Z_StrDup(cv_skin2.string);
|
|
||||||
|
|
||||||
if (CanChangeSkin(secondarydisplayplayer) && !P_PlayerMoving(secondarydisplayplayer))
|
|
||||||
{
|
|
||||||
SendNameAndColor2();
|
|
||||||
Z_Free(lastskinnames[1]);
|
|
||||||
lastskinnames[1] = Z_StrDup(cv_skin.string);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
|
|
||||||
CV_StealthSet(&cv_skin2, lastskinnames[1]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sends a color change for the console player, unless that player is moving.
|
/** Sends a color change for the console player, unless that player is moving.
|
||||||
|
|
Loading…
Reference in a new issue