I fixed your addkey() function a bit to avoid the nvault_lookup() call and to scan the key list before doing anything. It will also only add valid keys to the bitsum/vault. If a user tries to add 'gren', it will add the first found in the list that has 'gren' in it (hegrenade). On the 2nd attempt, it will say 'hegrenade' is already on the list. What would be cleaner is to scan the entire list for dupes and force the user to only enter a unique key value. You can work on that part. You should apply the below logic to your remkey() function.
PHP Code:
public addkey( id , level , cid ) { if( !cmd_access( id , level , cid , 2 ) ) return PLUGIN_HANDLED;
for( new i = 0 ; i < sizeof ( gKeyList ) ; i++ ) { if ( gKeyList[ i ][ 0 ] && ( containi( gKeyList[ i ] , szWeaponArg ) > -1 ) ) { if ( gBlockWeapons & ( 1 << i ) ) { client_print( id , print_console , "'%s' is already saved in the pick up manager list." , gKeyList[ i ] ); return PLUGIN_HANDLED; } else if ( !( gIgnoreWeapons & ( 1 << i ) ) ) { iFoundIndex = i; break; } } }
if ( iFoundIndex == -1 ) { client_print( id , print_console, "Unable to find the key '%s', type amx_cspum_keylist for all keys available to insert." , szWeaponArg ); } else { gBlockWeapons |= ( 1 << iFoundIndex );
So , insteand of using nvault_lookup() you've replace with checking if is in the bitfield no?
Just a little to make my logic, in your else if ( ) { ... there it is also returning if is NOT in bitfield not only the condition you've put with gIgnoreWeapon, i'm right?
The only thing that i do not understand it it is here:
PHP Code:
if ( gKeyList[ i ][ 0 ] && ( containi( gKeyList[ i ] , szWeaponArg ) > -1 ) )
What suppose to do gKeyList[i][0] ? you check if is not an empty spaces or what? why [0] ? It is the start or what .. i really have no idea what's means.
So , insteand of using nvault_lookup() you've replace with checking if is in the bitfield no?
Yes. All of your current blocked weapons are in the bitfield. It's pointless to call a native when you can just check the bitfield.
Quote:
Originally Posted by Craxor
Just a little to make my logic, in your else if ( ) { ... there it is also returning if is NOT in bitfield not only the condition you've put with gIgnoreWeapon, i'm right?
I removed the ignore weapon check and instead used just check the first character to see if it's empty. May be slightly more efficient, while not noticeable.
Quote:
Originally Posted by Craxor
The only thing that i do not understand it it is here:
PHP Code:
if ( gKeyList[ i ][ 0 ] && ( containi( gKeyList[ i ] , szWeaponArg ) > -1 ) )
See above comments. If ( ( theres a weapon in this slot ) AND ( arg exists in a key ) )
Quote:
Originally Posted by Craxor
What suppose to do gKeyList[i][0] ? you check if is not an empty spaces or what? why [0] ? It is the start or what .. i really have no idea what's means.
Your ignore list contained only those indexes where a weapon does not exist (""), so instead of doing the bit-wise &, I figured I'd just check if there is a weapon in that slot. IMO, you should not hard-code any ignore weapons.
I created a function for you to get the weapon index. It will either return weapon not found, duplicates found, or the weapon index. Instead of posting your plugin multiple times, I will modify what is posted here. Your addkey function should be good to go, try to apply similar to remkey().
So to my question, is doing the same thing as IgnoreWeapons .. now about your function , yes is better like that Thanks bugsy .. let my test now to see if is working weell
So to my question, is doing the same thing as IgnoreWeapons .. now about your function , yes is better like that Thanks bugsy .. let my test now to see if is working weell
Yes it does the same, I'll add comments later to help u understand
Bugsy i have problems in adding to remkey your fucntion, i tried like that:
PHP Code:
iFoundIndex = GetWeaponIndex( szWeaponArg );
if( iFoundIndex == GWI_NotFound ) { client_print( id, print_console, "This weapon '%s' is not saved yet or not exist, type amx_cspum_blockedlist to see all the keys blocked!", szWeaponArg ); return PLUGIN_HANDLED;
}
Wich is not working if i put 'x' or 'd' or a letter wich contain from the blocked weapons, btw, also i made a new function to show all the blocked weapons:
PHP Code:
public blockedlist( id, level, cid ) { if( !cmd_access( id , level, cid, 1 ) ) return PLUGIN_HANDLED;
client_print( id , print_console , " ~~ All blocked weapons ~~~ " );
for( new i = 0; i < sizeof( gKeyList ); i++ ) { if ( gKeyList[ i ][ 0 ] && !( gIgnoreWeapons & ( 1 << i ) ) && ( gBlockWeapons & ( 1 << i ) ) ) client_print( id , print_console , "%s", gKeyList[ i ] ); } return PLUGIN_HANDLED; }
About the problem , i cannot check with GWI_Notfound return if no index founded, Gwi duplicate return if chars from the contrained string are founded , but i want to avoid that, i want to force admin put the whole key... so i'm confuse, however, the whole code:
SMA
Code:
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <nvault>
#include <engine>
#include <cstrike>
#include <hamsandwich>
new const PLUGIN[] = "CS Pick up manager",
VERSION[] = "1.2",
AUTHOR[] = "Craxor";
new const gKeyList[][] =
{
"" ,
"p228" ,
"" ,
"scout" ,
"hegrenade" ,
"xm1014" ,
"c4" ,
"mac10" ,
"aug" ,
"smokegrenade" ,
"elite" ,
"fiveseven" ,
"ump45" ,
"sg550" ,
"galil" ,
"famas" ,
"usp" ,
"glock18" ,
"" ,
"mp5navy" ,
"m249" ,
"m3" ,
"m4a1" ,
"tmp" ,
"g3sg1" ,
"flashbang" ,
"deagle" ,
"sg552" ,
"ak47" ,
"" ,
"p90" ,
"shield"
};
//Added constants for the values returned by m_iType
enum ArmouryEntities
{
AE_MP5NAVY,
AE_TMP,
AE_P90,
AE_MAC10,
AE_AK47,
AE_SG552,
AE_M4A1,
AE_AUG,
AE_SCOUT,
AE_G3SG1,
AE_AWP,
AE_M3,
AE_XM1014,
AE_M249,
AE_FLASHBANG,
AE_HEGRENADE,
AE_VEST,
AE_VESTHELM,
AE_SMOKEGRENADE
}
enum ArmouryData
{
WeaponIndex,
WeaponName[ 14 ]
}
//Added array to give you the respective CSW_ weapon index and weapon string name based on the
//armoury_entity m_iType index value.
new const g_ArmouryTypes[ ArmouryEntities ][ ArmouryData ] =
{
{ CSW_MP5NAVY , "mp5" },
{ CSW_TMP , "tmp" },
{ CSW_P90 , "p90" },
{ CSW_MAC10 , "mac10" },
{ CSW_AK47 , "ak47" },
{ CSW_SG552 , "sg552" },
{ CSW_M4A1 , "m4a1" },
{ CSW_AUG , "aug" },
{ CSW_SCOUT , "scout" },
{ CSW_G3SG1 , "g3sg1" },
{ CSW_AWP , "awp" },
{ CSW_M3 , "m3" },
{ CSW_XM1014 , "xm1014" },
{ CSW_M249 , "m249" },
{ CSW_FLASHBANG , "flashbang" },
{ CSW_HEGRENADE , "he grenade" },
{ CSW_VEST , "vest" },
{ CSW_VESTHELM , "vest & helmet" },
{ CSW_SMOKEGRENADE , "smoke grenade" }
};
//Define constants for the touch forward so you know which weapon type was touched. Cleaner than
//assigning a 1 for weaponbox and armoury.
enum WeaponTypes
{
WT_Weaponbox,
WT_Armoury,
WT_Shield
}
//Define the cvar cspum_type values so the code makes more sense than using '1' or '2' and having to
//remember what action each corresponds to.
enum BlockType
{
BT_Remove = 1,
BT_BlockPickup
}
enum _:GetWeaponIndexValues
{
GWI_NotFound = -1,
GWI_Duplicate
}
new giTypeCvar;
new gNewVault;
new gBlockWeapons;
new gIgnoreWeapons = ( ( 1 << 0 ) | ( 1 << 2 ) | ( 1 << 18 ) | ( 1 << 29 ) );
new const gModelFile[] = "models/w_%s.mdl";
const CSW_SHIELD = 31;
const XoCArmoury = 4
const m_iCount = 35
const m_iType = 34;
#define IsArmoury(%1) (%1[0]=='a'&&%1[1]=='r'&&%1[7]=='_'&&%1[8]=='e'&&%1[12]=='t'&&%1[13]=='y')
#define IsWpBox(%1) (%1[0]=='w'&&%1[1]=='e'&&%1[5]=='n'&&%1[7]=='o'&&%1[8]=='x')
#define IsAShield(%1) (%1[0]=='w'&&%1[1]=='e'&&%1[7]=='s'&&%1[8]=='h'&&%1[9]=='i'&&%1[11]=='l'&&%1[12]=='d')
public plugin_init( )
{
register_plugin
(
.plugin_name = PLUGIN,
.version = VERSION,
.author = AUTHOR
);
gNewVault = nvault_open( "cspick_up_manager_vault" );
if( gNewVault == INVALID_HANDLE )
set_fail_state( "Problems openning cspick up manager vault." );
register_concmd( "amx_cspum_addkey" , "addkey" , ADMIN_BAN , " < Weapon key-name to block > " );
register_concmd( "amx_cspum_remkey" , "remkey" , ADMIN_BAN , " < Weapon key-name to block > " );
register_concmd( "amx_cspum_blocklist" , "block_all" , ADMIN_BAN );
register_concmd( "amx_cspum_resetlist" , "reset" , ADMIN_BAN );
register_concmd( "amx_cspum_keylist" , "showkeylist" , ADMIN_BAN );
register_concmd( "amx_cspum_blockedlist", "blockedlist" , ADMIN_BAN );
new EntityPlayerClass [] = "player";
register_touch( "armoury_entity" , EntityPlayerClass , "player_touch" );
register_touch( "weaponbox" , EntityPlayerClass , "player_touch" );
register_touch( "weapon_shield" , EntityPlayerClass , "player_touch" );
/*
cspum_type
"1"
*/
giTypeCvar = register_cvar( "cspum_type" , "2" );
}
public plugin_cfg()
{
new szModel[ 12 + 14 ] , szVal[ 2 ] , iTS;
for( new i = 0 ; i < sizeof ( gKeyList ) ; i++ )
{
if ( !( gIgnoreWeapons & ( 1 << i ) ) )
{
formatex( szModel , charsmax( szModel ) , gModelFile , gKeyList[ i ] );
if ( nvault_lookup( gNewVault , szModel , szVal , charsmax( szVal ) , iTS ) )
{
gBlockWeapons |= ( 1 << i );
}
}
}
}
public plugin_end()
{
nvault_close( gNewVault );
}
public addkey( id , level , cid )
{
if( !cmd_access( id , level , cid , 2 ) )
return PLUGIN_HANDLED;
new szWeaponArg[ 13 ] , szModelFile[ 12 + sizeof( gModelFile ) ] , iFoundIndex;
read_argv( 1 , szWeaponArg, charsmax( szWeaponArg ) );
iFoundIndex = GetWeaponIndex( szWeaponArg );
switch ( iFoundIndex )
{
case GWI_NotFound:
{
client_print( id , print_console, "Unable to find the key '%s', type amx_cspum_keylist for all keys available to insert." , szWeaponArg );
return PLUGIN_HANDLED;
}
case GWI_Duplicate:
{
client_print( id , print_console, "Duplicate weapons were found. Please be more specific with the weapon you want to add." , szWeaponArg );
return PLUGIN_HANDLED;
}
default:
{
if ( gBlockWeapons & ( 1 << iFoundIndex ) )
{
client_print( id , print_console , "'%s' is already saved in the pick up manager list." , gKeyList[ iFoundIndex ] );
return PLUGIN_HANDLED;
}
}
}
gBlockWeapons |= ( 1 << iFoundIndex );
formatex( szModelFile , charsmax( szModelFile ) , gModelFile , gKeyList[ iFoundIndex ] );
nvault_set( gNewVault , szModelFile , "1" );
client_print( id , print_console , "You successfully added '%s' to the list!" , gKeyList[ iFoundIndex ] );
return PLUGIN_HANDLED;
}
public remkey( id, level, cid )
{
if( !cmd_access( id, level, cid, 2 ) )
return PLUGIN_HANDLED;
new szWeaponArg[ 13 ] , szModelFile[ 12 + 14 ] , iFoundIndex , iEntity;
read_argv( 1, szWeaponArg, charsmax( szWeaponArg ) );
formatex( szModelFile , charsmax( szModelFile ) , gModelFile , szWeaponArg );
iFoundIndex = GetWeaponIndex( szWeaponArg );
if( iFoundIndex == GWI_NotFound )
{
client_print( id, print_console, "This weapon '%s' is not saved yet or not exist, type amx_cspum_blockedlist to see all the keys blocked!", szWeaponArg );
return PLUGIN_HANDLED;
}
if ( BlockType:get_pcvar_num( giTypeCvar ) == BT_Remove )
{
//Restore all armoury_entity's of this weapon type that have a 0 count.
while ( ( iEntity = find_ent_by_class( iEntity , "armoury_entity" ) ) )
{
if ( ( g_ArmouryTypes[ ArmouryEntities:get_pdata_int( iEntity , m_iType , XoCArmoury ) ][ WeaponIndex ] == iFoundIndex ) && ( get_pdata_int( iEntity , m_iCount , XoCArmoury ) == 0 ) )
{
set_pdata_int( iEntity , m_iCount , 1 , XoCArmoury );
set_pev( iEntity , pev_effects , ( pev( iEntity , pev_effects ) & ~EF_NODRAW ) );
set_pev( iEntity , pev_solid , SOLID_TRIGGER );
}
}
}
gBlockWeapons &= ~( 1 << iFoundIndex );
nvault_remove( gNewVault , szModelFile );
client_print( id , print_console, "You succesfully remove '%s' from the list!", szWeaponArg );
return PLUGIN_HANDLED;
}
public block_all( id, level, cid )
{
if( !cmd_access( id , level , cid , 1 ) )
return PLUGIN_HANDLED;
new szModelFile[ 12 + 14 ];
for( new i = 0 ; i < sizeof ( gKeyList ) ; i++ )
{
if ( !( gIgnoreWeapons & ( 1 << i ) ) && !( gBlockWeapons & ( 1 << i ) ) )
{
formatex( szModelFile , charsmax( szModelFile ), gModelFile , gKeyList[ i ] );
gBlockWeapons |= ( 1 << i );
nvault_set( gNewVault , szModelFile , "1" );
}
}
client_print( id, print_console, "All the weapons have been added inside of the list!" );
return PLUGIN_HANDLED;
}
public reset( id, level, cid )
{
if( !cmd_access( id , level , cid , 1 ) )
return PLUGIN_HANDLED;
new iEntity;
nvault_prune( gNewVault, 0, get_systime() );
client_print( id, print_console, "You've succesfully reseted all the list!" );
if ( BlockType:get_pcvar_num( giTypeCvar ) == BT_Remove )
{
//Restore all armoury_entity's that have a 0 count.
while ( ( iEntity = find_ent_by_class( iEntity , "armoury_entity" ) ) )
{
if ( get_pdata_int( iEntity , m_iCount , XoCArmoury ) == 0 )
{
set_pdata_int( iEntity , m_iCount , 1 , XoCArmoury );
set_pev( iEntity , pev_effects , ( pev( iEntity , pev_effects ) & ~EF_NODRAW ) );
set_pev( iEntity , pev_solid , SOLID_TRIGGER );
}
}
}
gBlockWeapons = 0;
return PLUGIN_HANDLED;
}
public showkeylist( id , level, cid )
{
if( !cmd_access( id, level, cid, 1 ) )
return PLUGIN_HANDLED;
client_print( id , print_console , "========== All weapons available to add to the list ========== " );
for( new i = 0; i < sizeof( gKeyList ); i++ )
{
if ( gKeyList[ i ][ 0 ] && !( gIgnoreWeapons & ( 1 << i ) ) )
client_print( id , print_console , " %s" , gKeyList[ i ] );
}
return PLUGIN_HANDLED;
}
public blockedlist( id, level, cid )
{
if( !cmd_access( id , level, cid, 1 ) )
return PLUGIN_HANDLED;
client_print( id , print_console , " ~~ All blocked weapons ~~~ " );
for( new i = 0; i < sizeof( gKeyList ); i++ )
{
if ( gKeyList[ i ][ 0 ] && !( gIgnoreWeapons & ( 1 << i ) ) && ( gBlockWeapons & ( 1 << i ) ) )
client_print( id , print_console , "%s", gKeyList[ i ] );
}
return PLUGIN_HANDLED;
}
public player_touch( ent , id )
{
if( !pev_valid( ent ) || !id || !( pev( ent , pev_flags) & FL_ONGROUND ) )
return -1;
new iWeaponID , szClassName[ 15 ] , WeaponTypes:wtType;
pev( ent , pev_classname , szClassName , charsmax( szClassName ) );
//Replaced iWeaponType variable with wtType. This way, wtType gets assigned a constant for the weapon type
//that it is. It makes more sense for people looking at your code to see the actual weapon type instead of
//1=armoury/weaponbox and 0=shield.
if( IsArmoury( szClassName ) )
{
iWeaponID = g_ArmouryTypes[ ArmouryEntities:get_pdata_int( ent , m_iType , XoCArmoury ) ][ WeaponIndex ];
wtType = WT_Armoury;
}
else if ( IsWpBox( szClassName ) )
{
iWeaponID = cs_get_weaponbox_type( ent );
wtType = WT_Weaponbox;
}
else if ( IsAShield( szClassName ) )
{
iWeaponID = CSW_SHIELD;
wtType = WT_Shield;
}
else
{
iWeaponID = 0;
}
if ( iWeaponID && ( gBlockWeapons & ( 1 << iWeaponID ) ) )
{
//Eliminated variable for the cvar value. Since the value is used only once, psas it
//directly into the switch.
switch( get_pcvar_num( giTypeCvar ) )
{
//Replaced magic numbers with constants so it's easier to understand what is going on.
case BT_Remove:
{
switch ( wtType )
{
//Added handling for armoury. Set count to 0 to make it disappear and set
//SOLID_NOT flag so no subsequent touches will occur.
case WT_Armoury:
{
set_pdata_int( ent , m_iCount , 0 , XoCArmoury );
set_pev( ent , pev_solid , SOLID_NOT );
}
case WT_Weaponbox:
{
call_think( ent );
}
case WT_Shield:
{
engfunc( EngFunc_RemoveEntity, ent );
}
}
}
case BT_BlockPickup:
{
return PLUGIN_HANDLED;
}
default:
{
return PLUGIN_CONTINUE;
}
}
}
return PLUGIN_CONTINUE;
}
cs_get_weaponbox_type( iWeaponBox )
{
new iWeapon
new const m_rgpPlayerItems_CWeaponBox[ 6 ] = { 34 , 35 , ... };
for ( new i = 1 ; i <= 5 ; i++ )
{
if( ( iWeapon = get_pdata_cbase( iWeaponBox , m_rgpPlayerItems_CWeaponBox[ i ] , XoCArmoury ) ) > 0 )
{
return cs_get_weapon_id( iWeapon )
}
}
return 0
}
GetWeaponIndex( const szKeyword[] )
{
new iFound = GWI_NotFound;
for ( new iWeapon = 1 ; iWeapon < sizeof( gKeyList ) ; iWeapon++ )
{
if ( containi( gKeyList[ iWeapon ] , szKeyword ) > -1 )
{
if ( iFound > GWI_NotFound )
{
iFound = GWI_Duplicate;
break;
}
else
{
iFound = iWeapon;
}
}
}
return iFound;
}
Wich is not working if i put 'x' or 'd' or a letter wich contain from the blocked weapons, btw, also i made a new function to show all the blocked weapons:
PHP Code:
public blockedlist( id, level, cid ) { if( !cmd_access( id , level, cid, 1 ) ) return PLUGIN_HANDLED;
client_print( id , print_console , " ~~ All blocked weapons ~~~ " );
for( new i = 0; i < sizeof( gKeyList ); i++ ) { if ( gKeyList[ i ][ 0 ] && !( gIgnoreWeapons & ( 1 << i ) ) && ( gBlockWeapons & ( 1 << i ) ) ) client_print( id , print_console , "%s", gKeyList[ i ] ); } return PLUGIN_HANDLED; }
You do not need to check both gKeyList[ i ][ 0 ] AND !( gIgnoreWeapons & ( 1 << i ) ) since they are the same thing. The only exception is if you wanted to hard-code an actual weapon on the ignore list. Currently you use this to only skip over the blank keys. Checking gKeyList[ i ][ 0 ] is enough.
Quote:
Originally Posted by Craxor
About the problem , i cannot check with GWI_Notfound return if no index founded, Gwi duplicate return if chars from the contrained string are founded , but i want to avoid that, i want to force admin put the whole key... so i'm confuse, however, the whole code:
Now that the code has been fixed to handle if no match is found or a dupe was found, you can allow partial weapon keyword usage, which I think is more user friendly. If someone is careless enough to try to block say hegrenade by using 'grenade' and it picks the wrong one, that is their fault. As long as they specify enough of the name ('m4a','smoke','heg',ak', etc), it will work perfectly.
Here is a fixed remkey() function (untested) and the FindWeaponIndex() function, with comments.
//Do not do your formatting here. You do not want to attempt to format the weapon based on what the user //typed. You want to use that to find the full weapon name in the list. Once that is found, do your formatex() //with the full weapon name from the list. //formatex( szModelFile , charsmax( szModelFile ) , gModelFile , szWeaponArg );
iFoundIndex = GetWeaponIndex( szWeaponArg );
//You should use a switch here, same that is done in the add function. /*if( iFoundIndex == GWI_NotFound ) { client_print( id, print_console, "This weapon '%s' is not saved yet or not exist, type amx_cspum_blockedlist to see all the keys blocked!", szWeaponArg ); return PLUGIN_HANDLED;
} */
switch ( iFoundIndex ) { case GWI_NotFound: { client_print( id , print_console, "Unable to find the key '%s', type amx_cspum_keylist for all keys available to insert." , szWeaponArg ); return PLUGIN_HANDLED; } case GWI_Duplicate: { client_print( id , print_console, "Duplicate weapons were found. Please be more specific with the weapon you want to add." , szWeaponArg ); return PLUGIN_HANDLED; } default: { //Instead of checking if it already exists as is done in the add command, check if it //does NOT exist so you can tell the user its not in the list therefore cannot be removed.. if ( !( gBlockWeapons & ( 1 << iFoundIndex ) ) ) { client_print( id , print_console , "'%s' is not currently in the pick up manager list." , gKeyList[ iFoundIndex ] ); return PLUGIN_HANDLED; } } }
if ( BlockType:get_pcvar_num( giTypeCvar ) == BT_Remove ) { //Restore all armoury_entity's of this weapon type that have a 0 count. while ( ( iEntity = find_ent_by_class( iEntity , "armoury_entity" ) ) ) { if ( ( g_ArmouryTypes[ ArmouryEntities:get_pdata_int( iEntity , m_iType , XoCArmoury ) ][ WeaponIndex ] == iFoundIndex ) && ( get_pdata_int( iEntity , m_iCount , XoCArmoury ) == 0 ) ) { set_pdata_int( iEntity , m_iCount , 1 , XoCArmoury ); set_pev( iEntity , pev_effects , ( pev( iEntity , pev_effects ) & ~EF_NODRAW ) ); set_pev( iEntity , pev_solid , SOLID_TRIGGER ); } } }
gBlockWeapons &= ~( 1 << iFoundIndex );
//Replace szWeaponArg with the full weapon name from the keylist since we have the weapon index that the user specified. formatex( szModelFile , charsmax( szModelFile ) , gModelFile , gKeyList[ iFoundIndex ] /*szWeaponArg*/ ); nvault_remove( gNewVault , szModelFile );
//Replace szWeaponArg with the full weapon name (same as above) client_print( id , print_console, "You succesfully removed '%s' from the list!", gKeyList[ iFoundIndex ] /*szWeaponArg*/ );
return PLUGIN_HANDLED; }
GetWeaponIndex( const szKeyword[] ) { //Start iFound value at GWI_NotFound. This way it returns this if nothing is found in the key list. new iFound = GWI_NotFound;
//Loop through the full key list (starting at 1 since 0 is empty) for ( new iWeapon = 1 ; iWeapon < sizeof( gKeyList ) ; iWeapon++ ) { //Check if keyword is containted in current weapon name if ( containi( gKeyList[ iWeapon ] , szKeyword ) > -1 ) { //Match found but this is not the first time a match was found since the iFound value was changed //from GWI_NotFound already. This means it is a duplicate, return as duplicate. if ( iFound > GWI_NotFound ) { iFound = GWI_Duplicate; break; } else { //Match found and htis is the first time since iFound = GWI_NotFound, set to weapon index. iFound = iWeapon; } } }