Added array element selection with Get/SetEntProp* on arrays (bug 4160, r=fyren).
This commit is contained in:
parent
f1a4a08c7f
commit
243b7e25f8
@ -967,21 +967,94 @@ static cell_t SetEntDataString(IPluginContext *pContext, const cell_t *params)
|
||||
class_name); \
|
||||
}
|
||||
|
||||
#define FIND_PROP_SEND(pProp) \
|
||||
#define CHECK_SET_PROP_DATA_OFFSET() \
|
||||
if (element >= td->fieldSize) \
|
||||
{ \
|
||||
return pContext->ThrowNativeError("Element %d is out of bounds (Prop %s has %d elements).", \
|
||||
element, \
|
||||
prop, \
|
||||
td->fieldSize); \
|
||||
} \
|
||||
\
|
||||
offset = GetTypeDescOffs(td) + (element * (td->fieldSizeInBytes / td->fieldSize));
|
||||
|
||||
#define FIND_PROP_SEND(type, type_name) \
|
||||
sm_sendprop_info_t info;\
|
||||
IServerUnknown *pUnk = (IServerUnknown *)pEntity; \
|
||||
IServerNetworkable *pNet = pUnk->GetNetworkable(); \
|
||||
if (!pNet) \
|
||||
{ \
|
||||
return pContext->ThrowNativeError("Edict %d (%d) is not networkable", g_HL2.ReferenceToIndex(params[1]), params[1]); \
|
||||
} \
|
||||
if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, pProp)) \
|
||||
if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, &info)) \
|
||||
{ \
|
||||
return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \
|
||||
prop, \
|
||||
params[1], \
|
||||
class_name); \
|
||||
} \
|
||||
\
|
||||
offset = info.actual_offset; \
|
||||
bit_count = info.prop->m_nBits; \
|
||||
\
|
||||
switch (info.prop->GetType()) \
|
||||
{ \
|
||||
case type: \
|
||||
{ \
|
||||
if (element > 0) \
|
||||
{ \
|
||||
return pContext->ThrowNativeError("SendProp %s is not an array. Element %d is invalid.", \
|
||||
prop, \
|
||||
element); \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
case DPT_DataTable: \
|
||||
{ \
|
||||
SendProp *pProp; \
|
||||
FIND_PROP_SEND_IN_SENDTABLE(info, pProp, element, type, type_name); \
|
||||
\
|
||||
offset += pProp->GetOffset(); \
|
||||
bit_count = pProp->m_nBits; \
|
||||
break; \
|
||||
} \
|
||||
default: \
|
||||
{ \
|
||||
return pContext->ThrowNativeError("SendProp %s type is not " type_name " (%d != %d)", \
|
||||
prop, \
|
||||
info.prop->GetType(), \
|
||||
type); \
|
||||
} \
|
||||
} \
|
||||
|
||||
#define FIND_PROP_SEND_IN_SENDTABLE(info, pProp, element, type, type_name) \
|
||||
SendTable *pTable = info.prop->GetDataTable(); \
|
||||
if (!pTable) \
|
||||
{ \
|
||||
return pContext->ThrowNativeError("Error looking up DataTable for prop %s", \
|
||||
prop); \
|
||||
} \
|
||||
\
|
||||
int elementCount = pTable->GetNumProps(); \
|
||||
if (element >= elementCount) \
|
||||
{ \
|
||||
return pContext->ThrowNativeError("Element %d is out of bounds (Prop %s has %d elements).", \
|
||||
element, \
|
||||
prop, \
|
||||
elementCount); \
|
||||
} \
|
||||
\
|
||||
pProp = pTable->GetProp(element); \
|
||||
if (pProp->GetType() != type) \
|
||||
{ \
|
||||
return pContext->ThrowNativeError("SendProp %s type is not " type_name " ([%d,%d] != %d)", \
|
||||
prop, \
|
||||
info.prop->GetType(), \
|
||||
info.prop->m_nBits, \
|
||||
type); \
|
||||
}
|
||||
|
||||
|
||||
inline int MatchFieldAsInteger(int field_type)
|
||||
{
|
||||
switch (field_type)
|
||||
@ -1005,6 +1078,75 @@ inline int MatchFieldAsInteger(int field_type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell_t GetEntPropArraySize(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
CBaseEntity *pEntity;
|
||||
char *prop;
|
||||
const char *class_name;
|
||||
edict_t *pEdict;
|
||||
|
||||
if (!IndexToAThings(params[1], &pEntity, &pEdict))
|
||||
{
|
||||
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
|
||||
}
|
||||
|
||||
if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
|
||||
{
|
||||
class_name = "";
|
||||
}
|
||||
|
||||
pContext->LocalToString(params[3], &prop);
|
||||
|
||||
switch (params[2])
|
||||
{
|
||||
case Prop_Data:
|
||||
{
|
||||
typedescription_t *td;
|
||||
|
||||
FIND_PROP_DATA(td);
|
||||
|
||||
return td->fieldSize;
|
||||
}
|
||||
case Prop_Send:
|
||||
{
|
||||
sm_sendprop_info_t info;
|
||||
|
||||
IServerUnknown *pUnk = (IServerUnknown *)pEntity;
|
||||
IServerNetworkable *pNet = pUnk->GetNetworkable();
|
||||
if (!pNet)
|
||||
{
|
||||
return pContext->ThrowNativeError("Edict %d (%d) is not networkable", g_HL2.ReferenceToIndex(params[1]), params[1]);
|
||||
}
|
||||
if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, &info))
|
||||
{
|
||||
return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)",
|
||||
prop,
|
||||
params[1],
|
||||
class_name);
|
||||
}
|
||||
|
||||
if (info.prop->GetType() != DPT_DataTable)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SendTable *pTable = info.prop->GetDataTable();
|
||||
if (!pTable)
|
||||
{
|
||||
return pContext->ThrowNativeError("Error looking up DataTable for prop %s", prop);
|
||||
}
|
||||
|
||||
return pTable->GetNumProps();
|
||||
}
|
||||
default:
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t GetEntProp(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
CBaseEntity *pEntity;
|
||||
@ -1014,6 +1156,12 @@ static cell_t GetEntProp(IPluginContext *pContext, const cell_t *params)
|
||||
edict_t *pEdict;
|
||||
int bit_count;
|
||||
|
||||
int element = 0;
|
||||
if (params[0] >= 5)
|
||||
{
|
||||
element = params[5];
|
||||
}
|
||||
|
||||
if (!IndexToAThings(params[1], &pEntity, &pEdict))
|
||||
{
|
||||
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
|
||||
@ -1042,26 +1190,13 @@ static cell_t GetEntProp(IPluginContext *pContext, const cell_t *params)
|
||||
td->fieldType);
|
||||
}
|
||||
|
||||
offset = GetTypeDescOffs(td);
|
||||
CHECK_SET_PROP_DATA_OFFSET();
|
||||
|
||||
break;
|
||||
}
|
||||
case Prop_Send:
|
||||
{
|
||||
sm_sendprop_info_t info;
|
||||
|
||||
FIND_PROP_SEND(&info);
|
||||
|
||||
if (info.prop->GetType() != DPT_Int)
|
||||
{
|
||||
return pContext->ThrowNativeError("SendProp %s is not an integer ([%d,%d] != %d)",
|
||||
prop,
|
||||
info.prop->GetType(),
|
||||
info.prop->m_nBits,
|
||||
DPT_Int);
|
||||
}
|
||||
|
||||
bit_count = info.prop->m_nBits;
|
||||
offset = info.actual_offset;
|
||||
FIND_PROP_SEND(DPT_Int, "integer");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1104,6 +1239,12 @@ static cell_t SetEntProp(IPluginContext *pContext, const cell_t *params)
|
||||
edict_t *pEdict;
|
||||
int bit_count;
|
||||
|
||||
int element = 0;
|
||||
if (params[0] >= 6)
|
||||
{
|
||||
element = params[6];
|
||||
}
|
||||
|
||||
if (!IndexToAThings(params[1], &pEntity, &pEdict))
|
||||
{
|
||||
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
|
||||
@ -1131,26 +1272,13 @@ static cell_t SetEntProp(IPluginContext *pContext, const cell_t *params)
|
||||
td->fieldType);
|
||||
}
|
||||
|
||||
offset = GetTypeDescOffs(td);
|
||||
CHECK_SET_PROP_DATA_OFFSET();
|
||||
|
||||
break;
|
||||
}
|
||||
case Prop_Send:
|
||||
{
|
||||
sm_sendprop_info_t info;
|
||||
|
||||
FIND_PROP_SEND(&info);
|
||||
|
||||
if (info.prop->GetType() != DPT_Int)
|
||||
{
|
||||
return pContext->ThrowNativeError("SendProp %s is not an integer ([%d,%d] != %d)",
|
||||
prop,
|
||||
info.prop->GetType(),
|
||||
info.prop->m_nBits,
|
||||
DPT_Int);
|
||||
}
|
||||
|
||||
bit_count = info.prop->m_nBits;
|
||||
offset = info.actual_offset;
|
||||
FIND_PROP_SEND(DPT_Int, "integer");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1194,9 +1322,16 @@ static cell_t GetEntPropFloat(IPluginContext *pContext, const cell_t *params)
|
||||
CBaseEntity *pEntity;
|
||||
char *prop;
|
||||
int offset;
|
||||
int bit_count;
|
||||
const char *class_name;
|
||||
edict_t *pEdict;
|
||||
|
||||
int element = 0;
|
||||
if (params[0] >= 4)
|
||||
{
|
||||
element = params[4];
|
||||
}
|
||||
|
||||
if (!IndexToAThings(params[1], &pEntity, &pEdict))
|
||||
{
|
||||
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
|
||||
@ -1227,24 +1362,13 @@ static cell_t GetEntPropFloat(IPluginContext *pContext, const cell_t *params)
|
||||
FIELD_TIME);
|
||||
}
|
||||
|
||||
offset = GetTypeDescOffs(td);
|
||||
CHECK_SET_PROP_DATA_OFFSET();
|
||||
|
||||
break;
|
||||
}
|
||||
case Prop_Send:
|
||||
{
|
||||
sm_sendprop_info_t info;
|
||||
|
||||
FIND_PROP_SEND(&info);
|
||||
|
||||
if (info.prop->GetType() != DPT_Float)
|
||||
{
|
||||
return pContext->ThrowNativeError("SendProp %s is not a float (%d != %d)",
|
||||
prop,
|
||||
info.prop->GetType(),
|
||||
DPT_Float);
|
||||
}
|
||||
|
||||
offset = info.actual_offset;
|
||||
FIND_PROP_SEND(DPT_Float, "float");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1263,9 +1387,16 @@ static cell_t SetEntPropFloat(IPluginContext *pContext, const cell_t *params)
|
||||
CBaseEntity *pEntity;
|
||||
char *prop;
|
||||
int offset;
|
||||
int bit_count;
|
||||
const char *class_name;
|
||||
edict_t *pEdict;
|
||||
|
||||
int element = 0;
|
||||
if (params[0] >= 5)
|
||||
{
|
||||
element = params[5];
|
||||
}
|
||||
|
||||
if (!IndexToAThings(params[1], &pEntity, &pEdict))
|
||||
{
|
||||
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
|
||||
@ -1296,24 +1427,13 @@ static cell_t SetEntPropFloat(IPluginContext *pContext, const cell_t *params)
|
||||
FIELD_TIME);
|
||||
}
|
||||
|
||||
offset = GetTypeDescOffs(td);
|
||||
CHECK_SET_PROP_DATA_OFFSET();
|
||||
|
||||
break;
|
||||
}
|
||||
case Prop_Send:
|
||||
{
|
||||
sm_sendprop_info_t info;
|
||||
|
||||
FIND_PROP_SEND(&info);
|
||||
|
||||
if (info.prop->GetType() != DPT_Float)
|
||||
{
|
||||
return pContext->ThrowNativeError("SendProp %s is not a float (%d != %d)",
|
||||
prop,
|
||||
info.prop->GetType(),
|
||||
DPT_Float);
|
||||
}
|
||||
|
||||
offset = info.actual_offset;
|
||||
FIND_PROP_SEND(DPT_Float, "float");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1337,9 +1457,16 @@ static cell_t GetEntPropEnt(IPluginContext *pContext, const cell_t *params)
|
||||
CBaseEntity *pEntity;
|
||||
char *prop;
|
||||
int offset;
|
||||
int bit_count;
|
||||
const char *class_name;
|
||||
edict_t *pEdict;
|
||||
|
||||
int element = 0;
|
||||
if (params[0] >= 4)
|
||||
{
|
||||
element = params[4];
|
||||
}
|
||||
|
||||
if (!IndexToAThings(params[1], &pEntity, &pEdict))
|
||||
{
|
||||
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
|
||||
@ -1368,24 +1495,13 @@ static cell_t GetEntPropEnt(IPluginContext *pContext, const cell_t *params)
|
||||
FIELD_EHANDLE);
|
||||
}
|
||||
|
||||
offset = GetTypeDescOffs(td);
|
||||
CHECK_SET_PROP_DATA_OFFSET();
|
||||
|
||||
break;
|
||||
}
|
||||
case Prop_Send:
|
||||
{
|
||||
sm_sendprop_info_t info;
|
||||
|
||||
FIND_PROP_SEND(&info);
|
||||
|
||||
if (info.prop->GetType() != DPT_Int)
|
||||
{
|
||||
return pContext->ThrowNativeError("SendProp %s is not an integer (%d != %d)",
|
||||
prop,
|
||||
info.prop->GetType(),
|
||||
DPT_Int);
|
||||
}
|
||||
|
||||
offset = info.actual_offset;
|
||||
FIND_PROP_SEND(DPT_Int, "integer");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1405,9 +1521,16 @@ static cell_t SetEntPropEnt(IPluginContext *pContext, const cell_t *params)
|
||||
CBaseEntity *pEntity;
|
||||
char *prop;
|
||||
int offset;
|
||||
int bit_count;
|
||||
const char *class_name;
|
||||
edict_t *pEdict;
|
||||
|
||||
int element = 0;
|
||||
if (params[0] >= 5)
|
||||
{
|
||||
element = params[5];
|
||||
}
|
||||
|
||||
if (!IndexToAThings(params[1], &pEntity, &pEdict))
|
||||
{
|
||||
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
|
||||
@ -1436,24 +1559,13 @@ static cell_t SetEntPropEnt(IPluginContext *pContext, const cell_t *params)
|
||||
FIELD_EHANDLE);
|
||||
}
|
||||
|
||||
offset = GetTypeDescOffs(td);
|
||||
CHECK_SET_PROP_DATA_OFFSET();
|
||||
|
||||
break;
|
||||
}
|
||||
case Prop_Send:
|
||||
{
|
||||
sm_sendprop_info_t info;
|
||||
|
||||
FIND_PROP_SEND(&info);
|
||||
|
||||
if (info.prop->GetType() != DPT_Int)
|
||||
{
|
||||
return pContext->ThrowNativeError("SendProp %s is not an integer (%d != %d)",
|
||||
prop,
|
||||
info.prop->GetType(),
|
||||
DPT_Int);
|
||||
}
|
||||
|
||||
offset = info.actual_offset;
|
||||
FIND_PROP_SEND(DPT_Int, "integer");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1494,8 +1606,15 @@ static cell_t GetEntPropVector(IPluginContext *pContext, const cell_t *params)
|
||||
CBaseEntity *pEntity;
|
||||
char *prop;
|
||||
int offset;
|
||||
int bit_count;
|
||||
const char *class_name;
|
||||
edict_t *pEdict;
|
||||
|
||||
int element = 0;
|
||||
if (params[0] >= 5)
|
||||
{
|
||||
element = params[5];
|
||||
}
|
||||
|
||||
if (!IndexToAThings(params[1], &pEntity, &pEdict))
|
||||
{
|
||||
@ -1527,24 +1646,13 @@ static cell_t GetEntPropVector(IPluginContext *pContext, const cell_t *params)
|
||||
FIELD_POSITION_VECTOR);
|
||||
}
|
||||
|
||||
offset = GetTypeDescOffs(td);
|
||||
CHECK_SET_PROP_DATA_OFFSET();
|
||||
|
||||
break;
|
||||
}
|
||||
case Prop_Send:
|
||||
{
|
||||
sm_sendprop_info_t info;
|
||||
|
||||
FIND_PROP_SEND(&info);
|
||||
|
||||
if (info.prop->GetType() != DPT_Vector)
|
||||
{
|
||||
return pContext->ThrowNativeError("SendProp %s is not a vector (%d != %d)",
|
||||
prop,
|
||||
info.prop->GetType(),
|
||||
DPT_Vector);
|
||||
}
|
||||
|
||||
offset = info.actual_offset;
|
||||
FIND_PROP_SEND(DPT_Vector, "vector");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1570,8 +1678,15 @@ static cell_t SetEntPropVector(IPluginContext *pContext, const cell_t *params)
|
||||
CBaseEntity *pEntity;
|
||||
char *prop;
|
||||
int offset;
|
||||
int bit_count;
|
||||
const char *class_name;
|
||||
edict_t *pEdict;
|
||||
|
||||
int element = 0;
|
||||
if (params[0] >= 5)
|
||||
{
|
||||
element = params[5];
|
||||
}
|
||||
|
||||
if (!IndexToAThings(params[1], &pEntity, &pEdict))
|
||||
{
|
||||
@ -1603,24 +1718,13 @@ static cell_t SetEntPropVector(IPluginContext *pContext, const cell_t *params)
|
||||
FIELD_POSITION_VECTOR);
|
||||
}
|
||||
|
||||
offset = GetTypeDescOffs(td);
|
||||
CHECK_SET_PROP_DATA_OFFSET();
|
||||
|
||||
break;
|
||||
}
|
||||
case Prop_Send:
|
||||
{
|
||||
sm_sendprop_info_t info;
|
||||
|
||||
FIND_PROP_SEND(&info);
|
||||
|
||||
if (info.prop->GetType() != DPT_Vector)
|
||||
{
|
||||
return pContext->ThrowNativeError("SendProp %s is not a vector (%d != %d)",
|
||||
prop,
|
||||
info.prop->GetType(),
|
||||
DPT_Vector);
|
||||
}
|
||||
|
||||
offset = info.actual_offset;
|
||||
FIND_PROP_SEND(DPT_Vector, "vector");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1654,6 +1758,12 @@ static cell_t GetEntPropString(IPluginContext *pContext, const cell_t *params)
|
||||
const char *class_name;
|
||||
edict_t *pEdict;
|
||||
bool bIsStringIndex;
|
||||
|
||||
int element = 0;
|
||||
if (params[0] >= 6)
|
||||
{
|
||||
element = params[6];
|
||||
}
|
||||
|
||||
if (!IndexToAThings(params[1], &pEntity, &pEdict))
|
||||
{
|
||||
@ -1690,14 +1800,46 @@ static cell_t GetEntPropString(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
bIsStringIndex = (td->fieldType != FIELD_CHARACTER);
|
||||
|
||||
if (bIsStringIndex && element >= td->fieldSize)
|
||||
{
|
||||
return pContext->ThrowNativeError("Element %d is out of bounds (Prop %s has %d elements).",
|
||||
element,
|
||||
prop,
|
||||
td->fieldSize);
|
||||
}
|
||||
else if (element > 1)
|
||||
{
|
||||
return pContext->ThrowNativeError("Prop %s is not an array. Element %d is invalid.",
|
||||
prop,
|
||||
element);
|
||||
}
|
||||
|
||||
offset = GetTypeDescOffs(td);
|
||||
if (bIsStringIndex)
|
||||
{
|
||||
offset += (element * (td->fieldSizeInBytes / td->fieldSize));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Prop_Send:
|
||||
{
|
||||
sm_sendprop_info_t info;
|
||||
|
||||
IServerUnknown *pUnk = (IServerUnknown *)pEntity;
|
||||
IServerNetworkable *pNet = pUnk->GetNetworkable();
|
||||
if (!pNet)
|
||||
{
|
||||
return pContext->ThrowNativeError("Edict %d (%d) is not networkable", g_HL2.ReferenceToIndex(params[1]), params[1]);
|
||||
}
|
||||
if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, &info))
|
||||
{
|
||||
return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)",
|
||||
prop,
|
||||
params[1],
|
||||
class_name);
|
||||
}
|
||||
|
||||
FIND_PROP_SEND(&info);
|
||||
offset = info.actual_offset;
|
||||
|
||||
if (info.prop->GetType() != DPT_String)
|
||||
{
|
||||
@ -1706,9 +1848,13 @@ static cell_t GetEntPropString(IPluginContext *pContext, const cell_t *params)
|
||||
info.prop->GetType(),
|
||||
DPT_String);
|
||||
}
|
||||
|
||||
offset = info.actual_offset;
|
||||
break;
|
||||
else if (element > 0)
|
||||
{
|
||||
return pContext->ThrowNativeError("SendProp %s is not an array. Element %d is invalid.",
|
||||
prop,
|
||||
element);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -2080,6 +2226,7 @@ REGISTER_NATIVES(entityNatives)
|
||||
{"GetEntDataString", GetEntDataString},
|
||||
{"GetEntDataVector", GetEntDataVector},
|
||||
{"GetEntProp", GetEntProp},
|
||||
{"GetEntPropArraySize", GetEntPropArraySize},
|
||||
{"GetEntPropEnt", GetEntPropEnt},
|
||||
{"GetEntPropFloat", GetEntPropFloat},
|
||||
{"GetEntPropString", GetEntPropString},
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* SourceMod (C)2004-2011 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
@ -504,10 +504,11 @@ stock GetEntSendPropOffs(ent, const String:prop[], bool:actual=false)
|
||||
* @param size Number of bytes to write (valid values are 1, 2, or 4).
|
||||
* This value is auto-detected, and the size parameter is
|
||||
* only used as a fallback in case detection fails.
|
||||
* @param element Element # (starting from 0) if property is an array.
|
||||
* @return Value at the given property offset.
|
||||
* @error Invalid entity or property not found.
|
||||
*/
|
||||
native GetEntProp(entity, PropType:type, const String:prop[], size=4);
|
||||
native GetEntProp(entity, PropType:type, const String:prop[], size=4, element=0);
|
||||
|
||||
/**
|
||||
* Sets an integer value in an entity's property.
|
||||
@ -518,13 +519,15 @@ native GetEntProp(entity, PropType:type, const String:prop[], size=4);
|
||||
* @param entity Entity/edict index.
|
||||
* @param type Property type.
|
||||
* @param prop Property name.
|
||||
* @param value Value to set.
|
||||
* @param size Number of bytes to write (valid values are 1, 2, or 4).
|
||||
* This value is auto-detected, and the size parameter is
|
||||
* only used as a fallback in case detection fails.
|
||||
* @param element Element # (starting from 0) if property is an array.
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetEntProp(entity, PropType:type, const String:prop[], any:value, size=4);
|
||||
native SetEntProp(entity, PropType:type, const String:prop[], any:value, size=4, element=0);
|
||||
|
||||
/**
|
||||
* Retrieves a float value from an entity's property.
|
||||
@ -535,10 +538,11 @@ native SetEntProp(entity, PropType:type, const String:prop[], any:value, size=4)
|
||||
* @param entity Entity/edict index.
|
||||
* @param type Property type.
|
||||
* @param prop Property name.
|
||||
* @param element Element # (starting from 0) if property is an array.
|
||||
* @return Value at the given property offset.
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
*/
|
||||
native Float:GetEntPropFloat(entity, PropType:type, const String:prop[]);
|
||||
native Float:GetEntPropFloat(entity, PropType:type, const String:prop[], element=0);
|
||||
|
||||
/**
|
||||
* Sets a float value in an entity's property.
|
||||
@ -550,10 +554,11 @@ native Float:GetEntPropFloat(entity, PropType:type, const String:prop[]);
|
||||
* @param type Property type.
|
||||
* @param prop Property name.
|
||||
* @param value Value to set.
|
||||
* @param element Element # (starting from 0) if property is an array.
|
||||
* @noreturn
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
*/
|
||||
native SetEntPropFloat(entity, PropType:type, const String:prop[], Float:value);
|
||||
native SetEntPropFloat(entity, PropType:type, const String:prop[], Float:value, element=0);
|
||||
|
||||
/**
|
||||
* Retrieves an entity index from an entity's property.
|
||||
@ -564,12 +569,13 @@ native SetEntPropFloat(entity, PropType:type, const String:prop[], Float:value);
|
||||
* @param entity Entity/edict index.
|
||||
* @param type Property type.
|
||||
* @param prop Property name.
|
||||
* @param element Element # (starting from 0) if property is an array.
|
||||
* @return Entity index at the given property.
|
||||
* If there is no entity, or the entity is not valid,
|
||||
* then -1 is returned.
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
*/
|
||||
native GetEntPropEnt(entity, PropType:type, const String:prop[]);
|
||||
native GetEntPropEnt(entity, PropType:type, const String:prop[], element=0);
|
||||
|
||||
/**
|
||||
* Sets an entity index in an entity's property.
|
||||
@ -581,10 +587,11 @@ native GetEntPropEnt(entity, PropType:type, const String:prop[]);
|
||||
* @param type Property type.
|
||||
* @param prop Property name.
|
||||
* @param other Entity index to set, or -1 to unset.
|
||||
* @param element Element # (starting from 0) if property is an array.
|
||||
* @noreturn
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
*/
|
||||
native SetEntPropEnt(entity, PropType:type, const String:prop[], other);
|
||||
native SetEntPropEnt(entity, PropType:type, const String:prop[], other, element=0);
|
||||
|
||||
/**
|
||||
* Retrieves a vector of floats from an entity, given a named network property.
|
||||
@ -596,11 +603,12 @@ native SetEntPropEnt(entity, PropType:type, const String:prop[], other);
|
||||
* @param type Property type.
|
||||
* @param prop Property name.
|
||||
* @param vec Vector buffer to store data in.
|
||||
* @param element Element # (starting from 0) if property is an array.
|
||||
* @noreturn
|
||||
* @error Invalid entity, property not found, or property not
|
||||
* actually a vector data type.
|
||||
*/
|
||||
native GetEntPropVector(entity, PropType:type, const String:prop[], Float:vec[3]);
|
||||
native GetEntPropVector(entity, PropType:type, const String:prop[], Float:vec[3], element=0);
|
||||
|
||||
/**
|
||||
* Sets a vector of floats in an entity, given a named network property.
|
||||
@ -612,11 +620,12 @@ native GetEntPropVector(entity, PropType:type, const String:prop[], Float:vec[3]
|
||||
* @param type Property type.
|
||||
* @param prop Property name.
|
||||
* @param vec Vector to set.
|
||||
* @param element Element # (starting from 0) if property is an array.
|
||||
* @noreturn
|
||||
* @error Invalid entity, property not found, or property not
|
||||
* actually a vector data type.
|
||||
*/
|
||||
native SetEntPropVector(entity, PropType:type, const String:prop[], const Float:vec[3]);
|
||||
native SetEntPropVector(entity, PropType:type, const String:prop[], const Float:vec[3], element=0);
|
||||
|
||||
/**
|
||||
* Gets a network property as a string.
|
||||
@ -626,10 +635,11 @@ native SetEntPropVector(entity, PropType:type, const String:prop[], const Float:
|
||||
* @param prop Property to use.
|
||||
* @param buffer Destination string buffer.
|
||||
* @param maxlen Maximum length of output string buffer.
|
||||
* @param element Element # (starting from 0) if property is an array.
|
||||
* @return Number of non-null bytes written.
|
||||
* @error Invalid entity, offset out of reasonable bounds, or property is not a valid string.
|
||||
*/
|
||||
native GetEntPropString(entity, PropType:type, const String:prop[], String:buffer[], maxlen);
|
||||
native GetEntPropString(entity, PropType:type, const String:prop[], String:buffer[], maxlen, element=0);
|
||||
|
||||
/**
|
||||
* Sets a network property as a string.
|
||||
@ -646,6 +656,17 @@ native GetEntPropString(entity, PropType:type, const String:prop[], String:buffe
|
||||
*/
|
||||
native SetEntPropString(entity, PropType:type, const String:prop[], const String:buffer[]);
|
||||
|
||||
/**
|
||||
* Retrieves the count of values that an entity property's array can store.
|
||||
*
|
||||
* @param entity Entity/edict index.
|
||||
* @param type Property type.
|
||||
* @param prop Property name.
|
||||
* @return Size of array (in elements) or 1 if property is not an array.
|
||||
* @error Invalid entity or property not found.
|
||||
*/
|
||||
native GetEntPropArraySize(entity, PropType:type, const String:prop[]);
|
||||
|
||||
/**
|
||||
* Copies an array of cells from an entity at a given offset.
|
||||
*
|
||||
|
163
plugins/testsuite/entpropelements.sp
Normal file
163
plugins/testsuite/entpropelements.sp
Normal file
@ -0,0 +1,163 @@
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
|
||||
// Coverage:
|
||||
// GetEntPropArraySize - PropSend/PropData
|
||||
|
||||
// GetEntPropString - PropData
|
||||
|
||||
// GetEntProp - PropSend/PropData
|
||||
// GetEntPropEnt - PropSend/PropData
|
||||
|
||||
// SetEntProp - PropSend/PropData
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
RegConsoleCmd("sm_listammo", sm_listammo, "sm_listammo <send|data> [target] - Lists current ammo for self or specified player");
|
||||
RegConsoleCmd("sm_listweapons", sm_listweapons, "sm_listweapons <send|data> [target] - Lists current weapons for self or specified player");
|
||||
RegConsoleCmd("sm_setammo", sm_setammo, "sm_setammo <ammotype> <amount> <send|data> [target]");
|
||||
RegConsoleCmd("sm_teststrings", sm_teststrings);
|
||||
}
|
||||
|
||||
public Action:sm_listammo(client, argc)
|
||||
{
|
||||
decl String:buffer[64];
|
||||
new target = client;
|
||||
if (argc >= 2)
|
||||
{
|
||||
GetCmdArg(2, buffer, sizeof(buffer));
|
||||
target = FindTarget(client, buffer, false, false);
|
||||
if (target <= 0)
|
||||
{
|
||||
ReplyToCommand(client, "Bad client");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
else if (client == 0)
|
||||
{
|
||||
ReplyToCommand(client, "Dillweed");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new PropType:proptype = PropType:-1;
|
||||
GetCmdArg(1, buffer, sizeof(buffer));
|
||||
if (!strcmp(buffer, "send"))
|
||||
proptype = Prop_Send;
|
||||
else if (!strcmp(buffer, "data"))
|
||||
proptype = Prop_Data;
|
||||
|
||||
new ammo;
|
||||
new max = GetEntPropArraySize(target, proptype, "m_iAmmo");
|
||||
for (new i = 0; i < max; i++)
|
||||
{
|
||||
if ((ammo = GetEntProp(target, proptype, "m_iAmmo", _, i)) > 0)
|
||||
ReplyToCommand(client, "Slot %d, Ammo %d", i, ammo);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:sm_listweapons(client, argc)
|
||||
{
|
||||
decl String:buffer[64];
|
||||
new target = client;
|
||||
if (argc >= 2)
|
||||
{
|
||||
GetCmdArg(2, buffer, sizeof(buffer));
|
||||
target = FindTarget(client, buffer, false, false);
|
||||
if (target <= 0)
|
||||
{
|
||||
ReplyToCommand(client, "Bad client");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
else if (client == 0)
|
||||
{
|
||||
ReplyToCommand(client, "Dillweed");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new PropType:proptype = PropType:-1;
|
||||
GetCmdArg(1, buffer, sizeof(buffer));
|
||||
if (!strcmp(buffer, "send"))
|
||||
proptype = Prop_Send;
|
||||
else if (!strcmp(buffer, "data"))
|
||||
proptype = Prop_Data;
|
||||
|
||||
new weapon, String:classname[64];
|
||||
new max = GetEntPropArraySize(target, proptype, "m_hMyWeapons");
|
||||
for (new i = 0; i < max; i++)
|
||||
{
|
||||
if ((weapon = GetEntPropEnt(target, proptype, "m_hMyWeapons", i)) == -1)
|
||||
continue;
|
||||
|
||||
GetEdictClassname(weapon, classname, sizeof(classname));
|
||||
ReplyToCommand(client, "Slot %d - \"%s\"", i, classname);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:sm_setammo(client, argc)
|
||||
{
|
||||
decl String:buffer[64];
|
||||
new target = client;
|
||||
if (argc >= 4)
|
||||
{
|
||||
GetCmdArg(4, buffer, sizeof(buffer));
|
||||
target = FindTarget(client, buffer, false, false);
|
||||
if (target <= 0)
|
||||
{
|
||||
ReplyToCommand(client, "Bad client");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
else if (client == 0)
|
||||
{
|
||||
ReplyToCommand(client, "Dillweed");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new PropType:proptype = PropType:-1;
|
||||
GetCmdArg(3, buffer, sizeof(buffer));
|
||||
if (!strcmp(buffer, "send"))
|
||||
proptype = Prop_Send;
|
||||
else if (!strcmp(buffer, "data"))
|
||||
proptype = Prop_Data;
|
||||
|
||||
new max = GetEntPropArraySize(target, proptype, "m_iAmmo");
|
||||
|
||||
GetCmdArg(1, buffer, sizeof(buffer));
|
||||
new ammotype = StringToInt(buffer);
|
||||
|
||||
if (ammotype >= max)
|
||||
{
|
||||
ReplyToCommand(client, "Ammotype out of bounds");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
GetCmdArg(2, buffer, sizeof(buffer));
|
||||
new amount = StringToInt(buffer);
|
||||
|
||||
SetEntProp(target, proptype, "m_iAmmo", amount, _, ammotype);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:sm_teststrings(client, argc)
|
||||
{
|
||||
new gpe = CreateEntityByName("game_player_equip");
|
||||
DispatchKeyValue(gpe, "tf_weapon_rocketlauncher", "2");
|
||||
DispatchKeyValue(gpe, "tf_weapon_pistol", "1");
|
||||
|
||||
decl String:value[64];
|
||||
for (new i = 0; i < 2; i++)
|
||||
{
|
||||
GetEntPropString(gpe, Prop_Data, "m_weaponNames", value, sizeof(value), i);
|
||||
ReplyToCommand(client, "At %d, I see a \"%s\"", i, value);
|
||||
}
|
||||
|
||||
AcceptEntityInput(gpe, "Kill");
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
Loading…
Reference in New Issue
Block a user