Added array element selection with Get/SetEntProp* on arrays (bug 4160, r=fyren).

This commit is contained in:
Nicholas Hastings 2011-06-05 21:52:36 -04:00
parent f1a4a08c7f
commit 243b7e25f8
3 changed files with 463 additions and 132 deletions

View File

@ -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},

View File

@ -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.
*

View 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;
}