source-sdk-2013-mapbase/sp/src/game/server/variant_t.cpp
Blixibon 87cd9b24bb Mapbase v6.1
- Added postprocess_controller entity from later versions of Source
- Added env_dof_controller entity from later versions of Source
- Added SDK_Engine_Post and DepthOfField shaders from the Momentum repo/Alien Swarm SDK
- Fixed auto-breaking game_text/choreo text not null terminating
- Fixed console groups showing up at the wrong developer levels
- Added more mesages to console groups, including a new "NPC AI" console group
- Fixed typos and added elaboration in various cvars, console messages, etc.
- Fixed npc_metropolice not using frag grenades correctly when allowed to use them
- Fixed npc_metropolice not registering stitching squad slots in AI
- Fixed SetModel input late precache warning
- Fixed env_global_light angles resetting upon loading a save
- Fixed an issue with ScriptKeyValuesRead using the wrong name and having a memory leak
- Allowed VScript functions which return null strings to actually return null instead of empty strings
- Added VScript member variable documentation
- Fixed VScript documentation lines sometimes mixing together
- Fixed VScript singletons having a ! at the beginning of descriptions
- Added Color struct to VScript and allowed color-related inputs to use it
- Added more VScript functions for weapons, ammo, ragdolling, and response contexts
- Added GameRules singleton for VScript
- Exposed AI interaction system to VScript
- Recovered some lost documentation from older revisions of the Mapbase wiki
- Added a way to get the current game's load type in VScript
- Fixed Precache/SpawnEntityFromTable not accounting for a few important field types
- Added VScript functions for getting a player's eye vectors
- Fixed a crash caused by removing the active weapon of a Combine soldier while it's firing
- Changed the way metrocops deploy their manhacks so they could use their manhack death response properly
- Fixed "Use Server" keyvalue on game_convar_mod not working
- Adjusted CAI_Expresser in VScript
2020-12-17 03:38:23 +00:00

285 lines
7.4 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "variant_t.h"
#ifdef MAPBASE
#include "mapbase/variant_tools.h"
#include "mapbase/matchers.h"
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
void variant_t::SetEntity( CBaseEntity *val )
{
eVal = val;
fieldType = FIELD_EHANDLE;
}
#ifdef MAPBASE
const char *variant_t::GetDebug()
{
/*
case FIELD_BOOLEAN: *((bool *)data) = bVal != 0; break;
case FIELD_CHARACTER: *((char *)data) = iVal; break;
case FIELD_SHORT: *((short *)data) = iVal; break;
case FIELD_INTEGER: *((int *)data) = iVal; break;
case FIELD_STRING: *((string_t *)data) = iszVal; break;
case FIELD_FLOAT: *((float *)data) = flVal; break;
case FIELD_COLOR32: *((color32 *)data) = rgbaVal; break;
case FIELD_VECTOR:
case FIELD_POSITION_VECTOR:
{
((float *)data)[0] = vecVal[0];
((float *)data)[1] = vecVal[1];
((float *)data)[2] = vecVal[2];
break;
}
case FIELD_EHANDLE: *((EHANDLE *)data) = eVal; break;
case FIELD_CLASSPTR: *((CBaseEntity **)data) = eVal; break;
*/
const char *fieldtype = "unknown";
switch (FieldType())
{
case FIELD_VOID: fieldtype = "Void"; break;
case FIELD_FLOAT: fieldtype = "Float"; break;
case FIELD_STRING: fieldtype = "String"; break;
case FIELD_INTEGER: fieldtype = "Integer"; break;
case FIELD_BOOLEAN: fieldtype = "Boolean"; break;
case FIELD_EHANDLE: fieldtype = "Entity"; break;
case FIELD_CLASSPTR: fieldtype = "EntityPtr"; break;
case FIELD_POSITION_VECTOR:
case FIELD_VECTOR: fieldtype = "Vector"; break;
case FIELD_CHARACTER: fieldtype = "Character"; break;
case FIELD_SHORT: fieldtype = "Short"; break;
case FIELD_COLOR32: fieldtype = "Color32"; break;
default: fieldtype = UTIL_VarArgs("unknown: %i", FieldType());
}
return UTIL_VarArgs("%s (%s)", String(), fieldtype);
}
#ifdef MAPBASE_VSCRIPT
void variant_t::SetScriptVariant( ScriptVariant_t &var )
{
switch (FieldType())
{
case FIELD_VOID: var = NULL; break;
case FIELD_INTEGER: var = iVal; break;
case FIELD_FLOAT: var = flVal; break;
case FIELD_STRING: var = STRING(iszVal); break;
case FIELD_POSITION_VECTOR:
case FIELD_VECTOR: var = reinterpret_cast<Vector*>(&flVal); break; // HACKHACK
case FIELD_BOOLEAN: var = bVal; break;
case FIELD_EHANDLE: var = ToHScript( eVal ); break;
case FIELD_CLASSPTR: var = ToHScript( eVal ); break;
case FIELD_SHORT: var = (short)iVal; break;
case FIELD_CHARACTER: var = (char)iVal; break;
case FIELD_COLOR32:
{
Color *clr = new Color( rgbaVal.r, rgbaVal.g, rgbaVal.b, rgbaVal.a );
var = g_pScriptVM->RegisterInstance( clr, true );
break;
}
default: var = ToString(); break;
}
}
#endif
// cmp1 = val1 float
// cmp2 = val2 float
#define VariantToFloat(val1, val2, lenallowed) \
float cmp1 = val1.Float() ? val1.Float() : val1.Int(); \
float cmp2 = val2.Float() ? val2.Float() : val2.Int(); \
if (lenallowed && val2.FieldType() == FIELD_STRING) \
cmp2 = strlen(val2.String());
// Integer parsing has been deactivated for consistency's sake. They now become floats only.
#define INTEGER_PARSING_DEACTIVATED 1
// "intchar" is the result of me not knowing where to find a version of isdigit that applies to negative numbers and floats.
#define intchar(c) (c >= '-' && c <= '9')
// Attempts to determine the field type from whatever is in the string and creates a variant_t with the converted value and resulting field type.
// Right now, Int/Float, String, and Vector are the only fields likely to be used by entities in variant_t parsing, so they're the only ones supported.
// Expand to other fields when necessary.
variant_t Variant_Parse(const char *szValue)
{
#ifdef INTEGER_PARSING_DEACTIVATED
bool isint = true;
bool isvector = false;
for (size_t i = 0; i < strlen(szValue); i++)
{
if (!intchar(szValue[i]))
{
isint = false;
if (szValue[i] == ' ')
isvector = true;
else
isvector = false;
}
}
variant_t var;
if (isint)
var.SetFloat(atof(szValue));
else if (isvector)
{
var.SetString(MAKE_STRING(szValue));
var.Convert(FIELD_VECTOR);
}
else
var.SetString(MAKE_STRING(szValue));
#else
bool isint = true;
bool isfloat = false;
for (size_t i = 0; i < strlen(szValue); i++)
{
if (szValue[i] == '.')
isfloat = true;
else if (!intchar(szValue[i]))
isint = false;
}
variant_t var = variant_t();
if (isint)
{
if (isfloat)
var.SetFloat(atof(szValue));
else
var.SetInt(atoi(szValue));
}
else
var.SetString(MAKE_STRING(szValue));
#endif
return var;
}
// Passes strings to Variant_Parse, uses the other input data for finding procedural entities.
variant_t Variant_ParseInput(inputdata_t inputdata)
{
if (inputdata.value.FieldType() == FIELD_STRING)
{
if (inputdata.value.String()[0] == '!')
{
variant_t var = variant_t();
var.SetEntity(gEntList.FindEntityProcedural(inputdata.value.String(), inputdata.pCaller, inputdata.pActivator, inputdata.pCaller));
if (var.Entity())
return var;
}
}
return Variant_Parse(inputdata.value.String());
}
// Passes string variants to Variant_Parse
variant_t Variant_ParseString(variant_t value)
{
if (value.FieldType() != FIELD_STRING)
return value;
return Variant_Parse(value.String());
}
bool Variant_Equal(variant_t val1, variant_t val2, bool bLenAllowed)
{
//if (!val2.Convert(val1.FieldType()))
// return false;
// Add more fields if they become necessary
switch (val1.FieldType())
{
case FIELD_INTEGER:
case FIELD_FLOAT:
{
VariantToFloat(val1, val2, bLenAllowed);
return cmp1 == cmp2;
}
case FIELD_BOOLEAN: return val1.Bool() == val2.Bool();
case FIELD_EHANDLE: return val1.Entity() == val2.Entity();
case FIELD_VECTOR:
{
Vector vec1; val1.Vector3D(vec1);
Vector vec2; val2.Vector3D(vec2);
return vec1 == vec2;
}
#ifdef MAPBASE_MATCHERS
// logic_compare allows wildcards on either string
default: return Matcher_NamesMatch_MutualWildcard(val1.String(), val2.String());
#else
default: return FStrEq(val1.String(), val2.String());
#endif
}
return false;
}
// val1 > val2
bool Variant_Greater(variant_t val1, variant_t val2, bool bLenAllowed)
{
//if (!val2.Convert(val1.FieldType()))
// return false;
// Add more fields if they become necessary
switch (val1.FieldType())
{
case FIELD_INTEGER:
case FIELD_FLOAT:
{
VariantToFloat(val1, val2, bLenAllowed);
return cmp1 > cmp2;
}
case FIELD_BOOLEAN: return val1.Bool() && !val2.Bool();
case FIELD_VECTOR:
{
Vector vec1; val1.Vector3D(vec1);
Vector vec2; val2.Vector3D(vec2);
return (vec1.x > vec2.x) && (vec1.y > vec2.y) && (vec1.z > vec2.z);
}
default: return strlen(val1.String()) > strlen(val2.String());
}
return false;
}
// val1 >= val2
bool Variant_GreaterOrEqual(variant_t val1, variant_t val2, bool bLenAllowed)
{
//if (!val2.Convert(val1.FieldType()))
// return false;
// Add more fields if they become necessary
switch (val1.FieldType())
{
case FIELD_INTEGER:
case FIELD_FLOAT:
{
VariantToFloat(val1, val2, bLenAllowed);
return cmp1 >= cmp2;
}
case FIELD_BOOLEAN: return val1.Bool() >= val2.Bool();
case FIELD_VECTOR:
{
Vector vec1; val1.Vector3D(vec1);
Vector vec2; val2.Vector3D(vec2);
return (vec1.x >= vec2.x) && (vec1.y >= vec2.y) && (vec1.z >= vec2.z);
}
default: return strlen(val1.String()) >= strlen(val2.String());
}
return false;
}
#endif