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

Solved [CS:GO] Reselecting grenades after throwing one


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Rosuav
Junior Member
Join Date: Aug 2018
Old 08-19-2018 , 22:45   [CS:GO] Reselecting grenades after throwing one
Reply With Quote #1

Hi! First-time post from someone who's read a lot of threads here without an account.

There appears to be a long-standing issue with having multiple of one grenade and nothing else (see CS:S thread https://forums.alliedmods.net/showthread.php?t=280143 ). Normally not an issue, since you'll have at least a knife, but if you create a game mode with knives disabled (setting mp_[c]t_default_melee to ""), you can get "stuck". Simplest way to demonstrate this: Buy two flashbangs and nothing else, throw one, and you can't throw the other.

Here's my partial solution. See also https://github.com/Rosuav/TF2BuffBot...ede41bee873a3b (don't mind the "TF2" part in there, this is a CS:GO plugin). MIT licensed.

Code:
public void OnPluginStart()
{
	HookEvent("weapon_fire", Event_weapon_fire);
}
//If you throw a grenade and it's the only thing you have, unselect.
public void Event_weapon_fire(Event event, const char[] name, bool dontBroadcast)
{
	int client = GetClientOfUserId(event.GetInt("userid"));
	if (GetPlayerWeaponSlot(client, 2) != -1) return; //Normally you'll have a knife, and things are fine.
	char weapon[64]; event.GetString("weapon", weapon, sizeof(weapon));
	int ammo_offset = 0;
	if (!strcmp(weapon, "weapon_hegrenade")) ammo_offset = 14;
	else if (!strcmp(weapon, "weapon_flashbang")) ammo_offset = 15;
	else if (!strcmp(weapon, "weapon_smokegrenade")) ammo_offset = 16;
	else if (!strcmp(weapon, "weapon_molotov") || !strcmp(weapon, "weapon_incgrenade")) ammo_offset = 17;
	else if (!strcmp(weapon, "weapon_decoy")) ammo_offset = 18;
	else return; //Wasn't a grenade you just threw.

	//Okay, you threw a grenade, and we know where to check its ammo.
	//Let's see if you have stock of anything else.
	if (GetPlayerWeaponSlot(client, 0) != -1) return; //Got a primary? All good.
	if (GetPlayerWeaponSlot(client, 1) != -1) return; //Got a pistol? All good.
	//Already checked knife above as our fast-abort.
	//Checking for a 'nade gives false positives.
	if (GetPlayerWeaponSlot(client, 5) != -1) return; //Got the C4? All good.

	//Do you have ammo of any other type of grenade?
	for (int offset = 14; offset <= 18; ++offset)
		if (offset != ammo_offset && GetEntProp(client, Prop_Data, "m_iAmmo", _, offset) > 0)
			//You have some other 'nade. Default behaviour is fine.
			return;

	//You don't have anything else. Unselect the current weapon, allowing you
	//to reselect your one and only grenade.
	CreateTimer(0.25, deselect_weapon, client, TIMER_FLAG_NO_MAPCHANGE);
}
Action deselect_weapon(Handle timer, any client)
{
	ignore(timer);
	SetEntPropEnt(client, Prop_Send, "m_hActiveWeapon", -1);
	//Ideally, I would like to now say "and select slot 4", but that doesn't seem
	//to work. It might also be possible to pick by a different slot (eg "slot7"
	//for flashbang), but I can't get that to work either.
}
Question: How can I make the plugin automatically reselect the grenade? I've tried EquipPlayerWeapon(client, GetPlayerWeaponSlot(client, 4)) and SetEntPropEnt(client, Prop_Send, "m_hActiveWeapon", GetPlayerWeaponSlot(client, 4)) and a variety of other variants. Would be grateful for any suggestions. (Including "you're going about this all wrong, here, do this tiny fix and it'll be solved in core".)

Last edited by Rosuav; 08-20-2018 at 02:09. Reason: Solved!
Rosuav is offline
sdz
Senior Member
Join Date: Feb 2012
Old 08-19-2018 , 23:07   Re: [CS:GO] Reselecting grenades after throwing one
Reply With Quote #2

have you tried ClientCommand(client, "use weapon_flashbang");
sdz is offline
Rosuav
Junior Member
Join Date: Aug 2018
Old 08-20-2018 , 00:26   Re: [CS:GO] Reselecting grenades after throwing one
Reply With Quote #3

Quote:
Originally Posted by sidezz View Post
have you tried ClientCommand(client, "use weapon_flashbang");
Based on the documentation, I actually hadn't:

"Note that this will not work on clients unless they have cl_restrict_server_commands set to 0."

But now you mention it, I've tried it. The form you gave didn't seem to work, but triggering "slot4" appears to. Thanks muchly!

I'm confused about the cvar though. Can't find it in my client. So now I have no idea whether the client can block this or not. For now, this will do.
Rosuav is offline
SHUFEN
Senior Member
Join Date: Jun 2014
Location: Japan, Tokyo
Old 08-20-2018 , 01:17   Re: [CS:GO] Reselecting grenades after throwing one
Reply With Quote #4

You can use this logic to force the equipping.

Code:
Handle g_hSwitchWeaponCall = null;

public void OnPluginStart()
{
	Handle hGameData = LoadGameConfigFile("sdkhooks.games");
	StartPrepSDKCall(SDKCall_Player);
	PrepSDKCall_SetFromConf(hGameData, SDKConf_Virtual, "Weapon_Switch");
	PrepSDKCall_AddParameter(SDKType_CBaseEntity, SDKPass_Pointer);
	PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
	g_hSwitchWeaponCall = EndPrepSDKCall();
	delete hGameData;
}

void YourFunction(int client, int weapon)
{
	SDKCall(g_hSwitchWeaponCall, client, weapon, 0);
	SetEntPropEnt(client, Prop_Send, "m_hActiveWeapon", weapon);
}
SHUFEN is offline
Send a message via Skype™ to SHUFEN
Rosuav
Junior Member
Join Date: Aug 2018
Old 08-20-2018 , 01:21   Re: [CS:GO] Reselecting grenades after throwing one
Reply With Quote #5

Interesting, SHUFEN.jp. Can you tell me how you knew the endpoints to access? I have no idea where any of that is documented.
Rosuav is offline
SHUFEN
Senior Member
Join Date: Jun 2014
Location: Japan, Tokyo
Old 08-20-2018 , 01:31   Re: [CS:GO] Reselecting grenades after throwing one
Reply With Quote #6

I don't remember this much, Maybe this was found while testing some virtual offsets.
SHUFEN is offline
Send a message via Skype™ to SHUFEN
MasterMind420
BANNED
Join Date: Nov 2010
Old 08-20-2018 , 01:33   Re: [CS:GO] Reselecting grenades after throwing one
Reply With Quote #7

ClientCommand as well as fakeclientcommand will work to forcibly switch players slots. Fakeclientcommand u pass the weapon string to. Ive used both of these methods in my backpack plugin.
MasterMind420 is offline
Rosuav
Junior Member
Join Date: Aug 2018
Old 08-20-2018 , 01:44   Re: [CS:GO] Reselecting grenades after throwing one
Reply With Quote #8

AIUI, FakeClientCommand is only for fake clients aka bots - it didn't appear to do anything for human players. I'm currently testing out the SDKCall version, and it appears to be working nicely.
Rosuav is offline
SHUFEN
Senior Member
Join Date: Jun 2014
Location: Japan, Tokyo
Old 08-20-2018 , 02:01   Re: [CS:GO] Reselecting grenades after throwing one
Reply With Quote #9

Yes. The difference between FakeClientCommand and ClientCommand is it will affects networked properties or else.
For example "sm_say <text>" is enough with FakeClientCommand. Because SayText 2 net messages are sent to each client after processing is done on the server side.
However, "use <weapon>" will not work as it must be applied on the client side for reasons such as view models and others.
SHUFEN is offline
Send a message via Skype™ to SHUFEN
sdz
Senior Member
Join Date: Feb 2012
Old 08-23-2018 , 05:11   Re: [CS:GO] Reselecting grenades after throwing one
Reply With Quote #10

Quote:
Originally Posted by Rosuav View Post
Interesting, SHUFEN.jp. Can you tell me how you knew the endpoints to access? I have no idea where any of that is documented.
https://asherkin.github.io/vtable/
sdz is offline
Reply



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 15:47.


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