mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-22 04:21:23 +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
|
||||
if ((variable->flags & CV_NOINIT) && !(variable->flags & CV_CALL))
|
||||
I_Error("variable %s has CV_NOINIT without CV_CALL\n", variable->name);
|
||||
if ((variable->flags & CV_CALL) && !variable->func)
|
||||
I_Error("variable %s has CV_CALL without a function\n", variable->name);
|
||||
if ((variable->flags & CV_CALL) && !(variable->func || variable->can_change))
|
||||
I_Error("variable %s has CV_CALL without any callbacks\n", variable->name);
|
||||
#endif
|
||||
|
||||
if (variable->flags & CV_NOINIT)
|
||||
|
@ -1496,12 +1496,35 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth)
|
|||
boolean override = false;
|
||||
INT32 overrideval = 0;
|
||||
|
||||
// If we want messages informing us if cheats have been enabled or disabled,
|
||||
// we need to rework the consvars a little bit. This call crashes the game
|
||||
// on load because not all variables will be registered at that time.
|
||||
/* boolean prevcheats = false;
|
||||
if (var->flags & CV_CHEAT)
|
||||
prevcheats = CV_CheatsEnabled(); */
|
||||
// raise 'can change' code
|
||||
LUA_CVarChanged(var); // let consolelib know what cvar this is.
|
||||
if (var->flags & CV_CALL && var->can_change && !stealth)
|
||||
{
|
||||
if (!var->can_change(valstr))
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
|
@ -1663,16 +1686,6 @@ found:
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -1685,8 +1698,7 @@ finish:
|
|||
}
|
||||
var->flags |= CV_MODIFIED;
|
||||
// raise 'on change' code
|
||||
LUA_CVarChanged(var); // let consolelib know what cvar this is.
|
||||
if (var->flags & CV_CALL && !stealth)
|
||||
if (var->flags & CV_CALL && var->func && !stealth)
|
||||
var->func();
|
||||
|
||||
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
|
||||
CV_PossibleValue_t *PossibleValue; // table of possible values
|
||||
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
|
||||
const char *string; // value in 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 */
|
||||
#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 }
|
||||
|
||||
#ifdef OLD22DEMOCOMPAT
|
||||
|
|
|
@ -300,6 +300,30 @@ static void Lua_OnChange(void)
|
|||
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)
|
||||
{
|
||||
const char *k;
|
||||
|
@ -458,6 +482,20 @@ static int lib_cvRegisterVar(lua_State *L)
|
|||
lua_pop(L, 1);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -672,6 +710,8 @@ int LUA_ConsoleLib(lua_State *L)
|
|||
lua_setfield(L, LUA_REGISTRYINDEX, "CV_PossibleValue");
|
||||
lua_newtable(L);
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "CV_OnChange");
|
||||
lua_newtable(L);
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "CV_CanChange");
|
||||
|
||||
// Push opaque CV_PossibleValue pointers
|
||||
// Because I don't care enough to bother.
|
||||
|
|
|
@ -109,6 +109,9 @@ static void Color2_OnChange(void);
|
|||
static void DummyConsvar_OnChange(void);
|
||||
static void SoundTest_OnChange(void);
|
||||
|
||||
static boolean Skin_CanChange(const char *valstr);
|
||||
static boolean Skin2_CanChange(const char *valstr);
|
||||
|
||||
#ifdef NETGAME_DEVMODE
|
||||
static void Fishcake_OnChange(void);
|
||||
#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);
|
||||
|
||||
// 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_playername2 = CVAR_INIT ("name2", "Tails", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name2_OnChange);
|
||||
// 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_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..
|
||||
consvar_t cv_skin = CVAR_INIT ("skin", DEFAULTSKIN, CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Skin_OnChange);
|
||||
consvar_t cv_skin2 = CVAR_INIT ("skin2", DEFAULTSKIN2, CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Skin2_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_WITH_CALLBACKS ("skin2", DEFAULTSKIN2, CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Skin2_OnChange, Skin2_CanChange);
|
||||
|
||||
// saved versions of the above six
|
||||
consvar_t cv_defaultplayercolor = CVAR_INIT ("defaultcolor", "Blue", CV_SAVE, Color_cons_t, NULL);
|
||||
|
@ -4792,6 +4794,41 @@ static void Name2_OnChange(void)
|
|||
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.
|
||||
* \sa cv_skin, Skin2_OnChange, Color_OnChange
|
||||
* \author Graue <graue@oceanbase.org>
|
||||
|
@ -4799,10 +4836,7 @@ static void Name2_OnChange(void)
|
|||
static void Skin_OnChange(void)
|
||||
{
|
||||
if (!Playing())
|
||||
return; // do whatever you want
|
||||
|
||||
if (lastskinnames[0] == NULL)
|
||||
lastskinnames[0] = Z_StrDup(cv_skin.string);
|
||||
return;
|
||||
|
||||
if (!(multiplayer || netgame)) // In single player.
|
||||
{
|
||||
|
@ -4818,17 +4852,7 @@ static void Skin_OnChange(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (CanChangeSkin(consoleplayer) && !P_PlayerMoving(consoleplayer))
|
||||
{
|
||||
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]);
|
||||
}
|
||||
SendNameAndColor();
|
||||
}
|
||||
|
||||
/** 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)
|
||||
{
|
||||
if (!Playing() || !splitscreen)
|
||||
return; // do whatever you want
|
||||
return;
|
||||
|
||||
if (lastskinnames[1] == NULL)
|
||||
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]);
|
||||
}
|
||||
SendNameAndColor2();
|
||||
}
|
||||
|
||||
/** Sends a color change for the console player, unless that player is moving.
|
||||
|
|
Loading…
Reference in a new issue