mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-27 22:42:57 +00:00
- Added three new ACS functions:
* int GetUserCVar(int playernum, "cvarname") * bool SetCVar("cvarname", newvalue) * bool SetUserCVar(int playernum, "cvarname", newvalue) GetUserCVar is analogous to GetCVar, except it returns the value of a user cvar for a specific player. (All user cvars can be examined using the playerinfo console command.) SetCVar sets a cvar to a new value. If the cvar is floating point, then newvalue is treated as a fixed point number, otherwise it's treated as an integer. SetUserCVar is the same, but for a specific player's user cvar. SetCVar and SetUserCVar can only change cvars created via CVARINFO. They cannot alter built-in cvars. If you use GetCVar or SetCVar with a user cvar, they will act on the copy of the user cvar for the player who activated the script. e.g. GetCVar("gender") is the same as GetUserCVar(PlayerNumber(), "gender") If you get the value of a floating point cvar, it will be returned as a fixed point number. Otherwise, it will be returned as an integer. SVN r4283 (trunk)
This commit is contained in:
parent
567fbace22
commit
167ee9e7fb
4 changed files with 168 additions and 17 deletions
|
@ -132,10 +132,10 @@ FBaseCVar::~FBaseCVar ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FBaseCVar::ForceSet (UCVarValue value, ECVarType type)
|
void FBaseCVar::ForceSet (UCVarValue value, ECVarType type, bool nouserinfosend)
|
||||||
{
|
{
|
||||||
DoSet (value, type);
|
DoSet (value, type);
|
||||||
if ((Flags & CVAR_USERINFO) && !(Flags & CVAR_IGNORE))
|
if ((Flags & CVAR_USERINFO) && !nouserinfosend && !(Flags & CVAR_IGNORE))
|
||||||
D_UserInfoChanged (this);
|
D_UserInfoChanged (this);
|
||||||
if (m_UseCallback)
|
if (m_UseCallback)
|
||||||
Callback ();
|
Callback ();
|
||||||
|
|
|
@ -101,7 +101,7 @@ public:
|
||||||
inline FBaseCVar *GetNext() const { return m_Next; }
|
inline FBaseCVar *GetNext() const { return m_Next; }
|
||||||
|
|
||||||
void CmdSet (const char *newval);
|
void CmdSet (const char *newval);
|
||||||
void ForceSet (UCVarValue value, ECVarType type);
|
void ForceSet (UCVarValue value, ECVarType type, bool nouserinfosend=false);
|
||||||
void SetGenericRep (UCVarValue value, ECVarType type);
|
void SetGenericRep (UCVarValue value, ECVarType type);
|
||||||
void ResetToDefault ();
|
void ResetToDefault ();
|
||||||
void SetArchiveBit () { Flags |= CVAR_ARCHIVE; }
|
void SetArchiveBit () { Flags |= CVAR_ARCHIVE; }
|
||||||
|
|
|
@ -430,7 +430,7 @@ void userinfo_t::Reset()
|
||||||
case NAME_PlayerClass: type = CVAR_Int; break;
|
case NAME_PlayerClass: type = CVAR_Int; break;
|
||||||
default: type = cvar->GetRealType(); break;
|
default: type = cvar->GetRealType(); break;
|
||||||
}
|
}
|
||||||
newcvar = C_CreateCVar(NULL, type, 0);
|
newcvar = C_CreateCVar(NULL, type, cvar->GetFlags() & CVAR_MOD);
|
||||||
newcvar->SetGenericRepDefault(cvar->GetGenericRepDefault(CVAR_String), CVAR_String);
|
newcvar->SetGenericRepDefault(cvar->GetGenericRepDefault(CVAR_String), CVAR_String);
|
||||||
Insert(cvarname, newcvar);
|
Insert(cvarname, newcvar);
|
||||||
}
|
}
|
||||||
|
|
177
src/p_acs.cpp
177
src/p_acs.cpp
|
@ -3474,6 +3474,9 @@ enum EACSFunctions
|
||||||
ACSF_VectorLength,
|
ACSF_VectorLength,
|
||||||
ACSF_SetHUDClipRect,
|
ACSF_SetHUDClipRect,
|
||||||
ACSF_SetHUDWrapWidth,
|
ACSF_SetHUDWrapWidth,
|
||||||
|
ACSF_SetCVar,
|
||||||
|
ACSF_GetUserCVar,
|
||||||
|
ACSF_SetUserCVar,
|
||||||
|
|
||||||
// ZDaemon
|
// ZDaemon
|
||||||
ACSF_GetTeamScore = 19620, // (int team)
|
ACSF_GetTeamScore = 19620, // (int team)
|
||||||
|
@ -3573,6 +3576,145 @@ static int GetUserVariable(AActor *self, FName varname, int index)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Converts fixed- to floating-point as required.
|
||||||
|
static void DoSetCVar(FBaseCVar *cvar, int value, bool force=false)
|
||||||
|
{
|
||||||
|
UCVarValue val;
|
||||||
|
ECVarType type;
|
||||||
|
|
||||||
|
// For serverinfo variables, only the arbitrator should set it.
|
||||||
|
// The actual change to this cvar will not show up until it's
|
||||||
|
// been replicated to all peers.
|
||||||
|
if ((cvar->GetFlags() & CVAR_SERVERINFO) && consoleplayer != Net_Arbitrator)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cvar->GetRealType() == CVAR_Float)
|
||||||
|
{
|
||||||
|
val.Float = FIXED2FLOAT(value);
|
||||||
|
type = CVAR_Float;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
val.Int = value;
|
||||||
|
type = CVAR_Int;
|
||||||
|
}
|
||||||
|
if (force)
|
||||||
|
{
|
||||||
|
cvar->ForceSet(val, type, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cvar->SetGenericRep(val, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts floating- to fixed-point as required.
|
||||||
|
static int DoGetCVar(FBaseCVar *cvar)
|
||||||
|
{
|
||||||
|
UCVarValue val;
|
||||||
|
|
||||||
|
if (cvar->GetRealType() == CVAR_Float)
|
||||||
|
{
|
||||||
|
val = cvar->GetGenericRep(CVAR_Float);
|
||||||
|
return FLOAT2FIXED(val.Float);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
val = cvar->GetGenericRep(CVAR_Int);
|
||||||
|
return val.Int;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int GetUserCVar(int playernum, const char *cvarname)
|
||||||
|
{
|
||||||
|
if ((unsigned)playernum >= MAXPLAYERS || !playeringame[playernum])
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
FBaseCVar **cvar_p = players[playernum].userinfo.CheckKey(FName(cvarname, true));
|
||||||
|
FBaseCVar *cvar;
|
||||||
|
if (cvar_p == NULL || (cvar = *cvar_p) == NULL || (cvar->GetFlags() & CVAR_IGNORE))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return DoGetCVar(cvar);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int GetCVar(AActor *activator, const char *cvarname)
|
||||||
|
{
|
||||||
|
FBaseCVar *cvar = FindCVar(cvarname, NULL);
|
||||||
|
// Either the cvar doesn't exist, or it's for a mod that isn't loaded, so return 0.
|
||||||
|
if (cvar == NULL || (cvar->GetFlags() & CVAR_IGNORE))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// For userinfo cvars, redirect to GetUserCVar
|
||||||
|
if (cvar->GetFlags() & CVAR_USERINFO)
|
||||||
|
{
|
||||||
|
if (activator == NULL || activator->player == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return GetUserCVar(int(activator->player - players), cvarname);
|
||||||
|
}
|
||||||
|
return DoGetCVar(cvar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int SetUserCVar(int playernum, const char *cvarname, int value)
|
||||||
|
{
|
||||||
|
if ((unsigned)playernum >= MAXPLAYERS || !playeringame[playernum])
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
FBaseCVar **cvar_p = players[playernum].userinfo.CheckKey(FName(cvarname, true));
|
||||||
|
FBaseCVar *cvar;
|
||||||
|
// Only mod-created cvars may be set.
|
||||||
|
if (cvar_p == NULL || (cvar = *cvar_p) == NULL || (cvar->GetFlags() & CVAR_IGNORE) || !(cvar->GetFlags() & CVAR_MOD))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DoSetCVar(cvar, value);
|
||||||
|
|
||||||
|
// If we are this player, then also reflect this change in the local version of this cvar.
|
||||||
|
if (playernum == consoleplayer)
|
||||||
|
{
|
||||||
|
FBaseCVar *cvar = FindCVar(cvarname, NULL);
|
||||||
|
// If we can find it in the userinfo, then we should also be able to find it in the normal cvar list,
|
||||||
|
// but check just to be safe.
|
||||||
|
if (cvar != NULL)
|
||||||
|
{
|
||||||
|
DoSetCVar(cvar, value, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int SetCVar(AActor *activator, const char *cvarname, int value)
|
||||||
|
{
|
||||||
|
FBaseCVar *cvar = FindCVar(cvarname, NULL);
|
||||||
|
// Only mod-created cvars may be set.
|
||||||
|
if (cvar == NULL || (cvar->GetFlags() & (CVAR_IGNORE|CVAR_NOSET)) || !(cvar->GetFlags() & CVAR_MOD))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// For userinfo cvars, redirect to SetUserCVar
|
||||||
|
if (cvar->GetFlags() & CVAR_USERINFO)
|
||||||
|
{
|
||||||
|
if (activator == NULL || activator->player == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return SetUserCVar(int(activator->player - players), cvarname, value);
|
||||||
|
}
|
||||||
|
DoSetCVar(cvar, value);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
|
int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
|
||||||
{
|
{
|
||||||
AActor *actor;
|
AActor *actor;
|
||||||
|
@ -4017,6 +4159,27 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
|
||||||
WrapWidth = argCount > 0 ? args[0] : 0;
|
WrapWidth = argCount > 0 ? args[0] : 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ACSF_GetUserCVar:
|
||||||
|
if (argCount == 2)
|
||||||
|
{
|
||||||
|
return GetUserCVar(args[0], FBehavior::StaticLookupString(args[1]));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACSF_SetUserCVar:
|
||||||
|
if (argCount == 3)
|
||||||
|
{
|
||||||
|
return SetUserCVar(args[0], FBehavior::StaticLookupString(args[1]), args[2]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACSF_SetCVar:
|
||||||
|
if (argCount == 2)
|
||||||
|
{
|
||||||
|
return SetCVar(activator, FBehavior::StaticLookupString(args[0]), args[1]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -6883,19 +7046,7 @@ scriptwait:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCD_GETCVAR:
|
case PCD_GETCVAR:
|
||||||
{
|
STACK(1) = GetCVar(activator, FBehavior::StaticLookupString(STACK(1)));
|
||||||
FBaseCVar *cvar = FindCVar (FBehavior::StaticLookupString (STACK(1)), NULL);
|
|
||||||
// Either the cvar doesn't exist, or it's for a mod that isn't loaded, so return 0.
|
|
||||||
if (cvar == NULL || (cvar->GetFlags() & CVAR_IGNORE))
|
|
||||||
{
|
|
||||||
STACK(1) = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UCVarValue val = cvar->GetGenericRep (CVAR_Int);
|
|
||||||
STACK(1) = val.Int;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCD_SETHUDSIZE:
|
case PCD_SETHUDSIZE:
|
||||||
|
|
Loading…
Reference in a new issue