Raised This Month: $32 Target: $400
 8% 

[HowTo] Detect weapon Drop/Touch details [including drop type, weapon type, etc]


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
VEN
Veteran Member
Join Date: Jan 2005
Old 12-30-2006 , 15:49   [HowTo] Detect weapon Drop/Touch details [including drop type, weapon type, etc]
Reply With Quote #1

I noticed that many coders dealing with weapon drop. Often they have problems with detection of some of the following details:
- WeaponBoxOwnerClientIndex
- WeaponDropType
- WeaponIndex
- WeaponName
- WeaponBoxEntityIndex
- WeaponEntityIndex
- WeaponBoxModel
Note: The weaponbox entity is not the actual weapon, it is the "box" entity that "contain" the weapon_* entity, i.e. the actual weapon entity. Of course weapon_* entities classnames (which equal to weapon names) are unique for the different weapon types. The actual weapon type is stored in the weapon's entity private data area that can be easily accessed via corresponding native function from the cstrike module.

This script shows how to retrieve the details that is listed above:
Code:
/* AMX Mod X *   Weapon Drop Details * * (c) Copyright 2007 by VEN * * This file is provided as is (no warranties) */ #include <amxmodx> #include <fakemeta> #include <cstrike> #define PLUGIN_NAME "Weapon Drop Details" #define PLUGIN_VERSION "0.1" #define PLUGIN_AUTHOR "VEN" enum droptype {     droptype_manual,     droptype_onbuy,     droptype_ondeath,     droptype_ondisconnect } new const g_drop_type[droptype][] = {     "Manual",     "OnBuy",     "OnDeath",     "OnDisconnect" } new const g_drop[] = "drop" #define MAX_PLAYERS 32 new g_command[MAX_PLAYERS + 1][sizeof g_drop + 1] new const g_wbox_class[] = "weaponbox" new const g_wbox_model[] = "models/w_weaponbox.mdl" new const g_wbox_model_prefix[] = "models/w_" stock const g_start_client_index = 1 new g_max_clients new g_max_entities public plugin_init() {     register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR)     register_forward(FM_SetModel, "forward_set_model")     g_max_clients = global_get(glb_maxClients)     g_max_entities = global_get(glb_maxEntities) } public client_command(id) {     read_argv(0, g_command[id], sizeof g_drop) } public forward_set_model(ent, const model[]) {     if (!pev_valid(ent) || !equali(model, g_wbox_model_prefix, sizeof g_wbox_model_prefix - 1) || equali(model, g_wbox_model))         return FMRES_IGNORED     new id = pev(ent, pev_owner)     if (!(g_start_client_index <= id <= g_max_clients))         return FMRES_IGNORED     static class[32]     pev(ent, pev_classname, class, sizeof class - 1)     if (!equal(class, g_wbox_class))         return FMRES_IGNORED     for (new i = g_max_clients + 1; i < g_max_entities; ++i) {         if (!pev_valid(i) || ent != pev(i, pev_owner))             continue         new wid = cs_get_weapon_id(i)         new droptype:drop_type         if (!is_user_connected(id))             drop_type = droptype_ondisconnect         else if (!is_user_alive(id))             drop_type = droptype_ondeath         else if (equal(g_command[id], g_drop))             drop_type = droptype_manual         else if (wid != CSW_C4)             drop_type = droptype_onbuy         else             return FMRES_IGNORED         pev(i, pev_classname, class, sizeof class - 1)         server_print("BoxOwnerClientIndex: %2d, DropType: %-12s, Index: %2d, Name: %-16s, BoxEntityIndex: %3d, EntityIndex: %3d, BoxModel: %s", id, g_drop_type[drop_type], wid, class, ent, i, model)         return FMRES_IGNORED     }     return FMRES_IGNORED }
Attached Files
File Type: sma Get Plugin or Get Source (weapon_drop_details.sma - 1525 views - 2.3 KB)

Last edited by VEN; 01-04-2007 at 18:18.
VEN is offline
VEN
Veteran Member
Join Date: Jan 2005
Old 01-04-2007 , 18:20   Re: [HowTo] Detect weapon Drop/Touch details [including drop type, weapon type, etc]
Reply With Quote #2

Here is the similar script but for Touch case, now with comments
Code:
/* AMX Mod X *   Weapon Touch Details * * (c) Copyright 2007 by VEN * * This file is provided as is (no warranties) */ #include <amxmodx> #include <fakemeta> #include <cstrike> #define PLUGIN_NAME "Weapon Touch Details" #define PLUGIN_VERSION "0.1" #define PLUGIN_AUTHOR "VEN" // comment to also process a weapons that isn't on the floor/ground #define SKIP_WEAPS_THAT_ISNT_ON_GROUND new const g_wbox_class[] = "weaponbox" new const g_wbox_model[] = "models/w_weaponbox.mdl" stock const g_wbox_custom_iuser_pev_num = pev_iuser3 stock const g_client_start_index = 1 new g_max_clients new g_max_entities public plugin_init() {     register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR)     register_forward(FM_Touch, "forward_touch")     g_max_clients = global_get(glb_maxClients)     g_max_entities = global_get(glb_maxEntities) } public forward_touch(ent, toucher) {     // if toucher isn't a client or entity isn't valid     if (!(g_client_start_index <= toucher <= g_max_clients) || !pev_valid(ent))         return FMRES_IGNORED #if defined SKIP_WEAPS_THAT_ISNT_ON_GROUND     // is weapon not on the floor/ground?     if (!engfunc(EngFunc_EntIsOnFloor, ent))         return FMRES_IGNORED #endif     // if this check is return true then this is a weaponbox that already touched by this player     // so to avoid flood of our informational text in the server console do not go further     if (pev(ent, g_wbox_custom_iuser_pev_num) == toucher)         return FMRES_IGNORED     static string[32]     pev(ent, pev_classname, string, sizeof string - 1)     // required entity classname are "weaponbox"     if (!equal(string, g_wbox_class))         return FMRES_IGNORED     new id = pev(ent, pev_owner)     // weaponbox must be owned by a player, in other case it is kind of invalid weaponbox o_O     if (!(g_client_start_index <= id <= g_max_clients))         return FMRES_IGNORED     pev(ent, pev_model, string, sizeof string - 1)     // if weaponbox model are "models/w_weaponbox.mdl" then weapon_* entity isn't linked to that weaponbox yet     if (equali(string, g_wbox_model))         return FMRES_IGNORED     for (new i = g_max_clients + 1; i < g_max_entities; ++i) {         // search for an entity that is owned by the weaponbox, this should be a weapon_* entity         if (!pev_valid(i) || ent != pev(i, pev_owner))             continue         // get a weapon type of the weapon_* entity         new wid = cs_get_weapon_id(i)         // the a clsssname of the weapon_* entity (it is equal to a weapon name)         pev(i, pev_classname, string, sizeof string - 1)         // set the toucher client index to the custom iuser pev field         set_pev(ent, g_wbox_custom_iuser_pev_num, toucher)         // output details to the server console         server_print("BoxToucherClientIndex: %2d, BoxOwnerClientIndex: %2d, Index: %2d, Name: %-16s, BoxEntityIndex: %3d, EntityIndex: %3d", toucher, id, wid, string, ent, i)         return FMRES_IGNORED     }     return FMRES_IGNORED }
Attached Files
File Type: sma Get Plugin or Get Source (weapon_touch_details.sma - 1433 views - 2.9 KB)
VEN is offline
XxAvalanchexX
Veteran Member
Join Date: Oct 2004
Location: abort73.com
Old 01-05-2007 , 21:28   Re: [HowTo] Detect weapon Drop/Touch details [including drop type, weapon type, etc]
Reply With Quote #3

Nice work! But, for this to distinguish properly between dropped manually and dropped on buy, I must assume that a client_command is called when a user buys something via clicking the menus?
__________________
No longer around. Thanks your support, everyone! As always:
THIS ONES FOR YOU
3000 PTS
XxAvalanchexX is offline
VEN
Veteran Member
Join Date: Jan 2005
Old 01-06-2007 , 14:21   Re: [HowTo] Detect weapon Drop/Touch details [including drop type, weapon type, etc]
Reply With Quote #4

Yes, the client_command is called on buy of course. But i didn't care to check that because any drop that isn't related to Manual/OnDeath/OnDisconnect should be OnBuy (at least for CS, i do not know another drop type). But i should warn that amxmodx/metamod plugins/modules could mess with the command checking by emulating the commands.
VEN is offline
Fredd
Veteran Member
Join Date: Jul 2007
Old 08-16-2007 , 06:53   Re: [HowTo] Detect weapon Drop/Touch details [including drop type, weapon type, etc]
Reply With Quote #5

Reallu usefull thank you VEM
__________________
Need a private coder? AMXX, SourceMOD, MMS? PM me!
Fredd is offline
stupok
Veteran Member
Join Date: Feb 2006
Old 08-16-2007 , 15:30   Re: [HowTo] Detect weapon Drop/Touch details [including drop type, weapon type, etc]
Reply With Quote #6

I wonder if you could figure out how to do this for The Specialists. I've tried similar methods to yours for trying to determine who dropped a weapon without success.

The classname of the dropped weapon is WorldGun, the pev_owner is always 0. I've tried accessing the pdata of WorldGun but the server crashes when I attempt to do so. Maybe I was accessing the pdata too soon? (FM_SetModel)

I've looked at pev_euser*, pev_fuser*, pev_iuser*, pev_vuser*, pev_controller, pev_controller_*, but none of these values have the id of the client who dropped the weapon. Most of the values are all 0. Only pev_fuser1 was 1.

If you can give me some ideas, I'll test them myself. I'd appreciate your input, VEN.

EDIT: I was accessing the pdata too soon. I threw in a set_task() to delay checking the pdata, but still no luck. No values that match the client's id.
__________________

Last edited by stupok; 08-16-2007 at 22:22.
stupok is offline
Shin Lee
Junior Member
Join Date: Aug 2006
Location: Germany
Old 08-16-2007 , 21:12   Re: [HowTo] Detect weapon Drop/Touch details [including drop type, weapon type, etc]
Reply With Quote #7

yea VEN please help us with this it looks a bit gay when i have my custom v_model & p_model but when i throw it away its the standard katana :O pleeeaaaseee help stupok with this
Shin Lee is offline
Send a message via ICQ to Shin Lee Send a message via MSN to Shin Lee
VEN
Veteran Member
Join Date: Jan 2005
Old 08-17-2007 , 13:06   Re: [HowTo] Detect weapon Drop/Touch details [including drop type, weapon type, etc]
Reply With Quote #8

Try this
Code:
        static Float:origin[3]         pev(ent, pev_origin, origin)         new x = FM_NULLENT         while ((x = engfunc(EngFunc_FindEntityInSphere, x, origin, 16.0))) {                 if (!(g_client_start_index <= x <= g_max_clients))                         continue                 static Float:v1[3], Float:v2[3]                 pev(x, pev_origin, v1)                 pev(x, pev_angles, v2)                 engfunc(EngFunc_MakeVectors, v2)                 global_get(glb_v_forward, v2)                 xs_vec_mul_scalar(v2, 10.0, v2)                 xs_vec_add(v1, v2, v1)                 if (!xs_vec_equal(v1, origin))                         continue                 server_print("WeaponOwnerClientIndex: %d", x)                 break         }
VEN is offline
stupok
Veteran Member
Join Date: Feb 2006
Old 08-17-2007 , 13:42   Re: [HowTo] Detect weapon Drop/Touch details [including drop type, weapon type, etc]
Reply With Quote #9

Thanks for your input, VEN.

I'm wondering, when should I execute that code? FM_SetOrigin?

EDIT:

I tried doing something similar on my own, checking for an entity in the sphere around the weapon that was dropped. However, it seems the weapon that was dropped is not assigned an origin until it collides with something. FM_SetOrigin is called on the dropped weapon when it hits a wall or touches the floor.

Here's what I'm doing:

Code:
public VEN_function(ent) {     static Float:origin[3]     pev(ent, pev_origin, origin)         server_print("ent origin: %f %f %f", origin[0], origin[1], origin[2])         new x = FM_NULLENT     while ((x = engfunc(EngFunc_FindEntityInSphere, x, origin, 16.0)))     {         server_print("x: %i", x)                 if (!(g_client_start_index <= x <= g_max_clients))             continue                 server_print("x is valid")                 static Float:v1[3], Float:v2[3]         pev(x, pev_origin, v1)         pev(x, pev_angles, v2)                 server_print("x origin: %f %f %f", v1[0], v1[1] ,v1[2])         server_print("x angles: %f %f %f", v2[0], v2[1], v2[2])                 engfunc(EngFunc_MakeVectors, v2)         global_get(glb_v_forward, v2)         xs_vec_mul_scalar(v2, 10.0, v2)         xs_vec_add(v1, v2, v1)                 server_print("modified v1: %f %f %f", v1[0], v1[1] ,v1[2])                 if (!xs_vec_equal(v1, origin))             continue                 server_print("WeaponOwnerClientIndex: %d", x)         break     } } public forward_SetModel(ent, model[]) {     if(equal(model, "models/w_katana.mdl"))     {         VEN_function(ent)     }         return FMRES_IGNORED }

Here is the output from my debug messages:

Code:
ent origin: 0.000000 0.000000 0.000000
x: 12
x: 13
x: 14
x: 15
x: 249
x: 250
(This is on a 10 slot server, g_client_start_index is set to 1)
__________________

Last edited by stupok; 08-17-2007 at 14:15.
stupok is offline
Shin Lee
Junior Member
Join Date: Aug 2006
Location: Germany
Old 08-18-2007 , 11:39   Re: [HowTo] Detect weapon Drop/Touch details [including drop type, weapon type, etc]
Reply With Quote #10

mhh and how does this work now Oo?
i mean how can i do that workin on my server with my w_model
Shin Lee is offline
Send a message via ICQ to Shin Lee Send a message via MSN to Shin Lee
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 01:41.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode