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

Spawn a rocket on button press


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
walabulu4
Junior Member
Join Date: Sep 2019
Old 10-04-2019 , 02:33   Spawn a rocket on button press
Reply With Quote #1

I want it on my server when the player hits the medic button he launches a rocket and it should be on a cool down. I was wondering where I could start looking to script a plugin like this or if it was simple to do. I have written simple plugins and have a little experience with sourcepawn.
walabulu4 is offline
nosoop
Veteran Member
Join Date: Aug 2014
Old 10-04-2019 , 06:52   Re: Spawn a rocket on button press
Reply With Quote #2

Is this for TF2? Since it looks like you're up for learning how to do it, here's some steps you can follow:
  1. Add a command listener to the "voicemenu" command and detect the "MEDIC!" call. You can use this snippet (ported to new syntax, ideally). Make sure it works by displaying some messages with PrintToChat or PrintToServer before moving on.
  2. Determine the position to spawn your rocket (likely with GetClientEyePosition and GetClientEyeAngles), then spawn your rocket. This snippet should be fine, though it's also in old syntax.
  3. Set up a cooldown. Create a float array for your players (size MAXPLAYERS + 1), then when you need to update your cooldown, set it to GetGameTime() + your_cooldown_amount. You can check if the cooldown has passed if GetGameTime() is larger than the array entry. Don't forget to zero out the time in an OnClientPutInServer() forward.
__________________
I do TF2, TF2 servers, and TF2 plugins.
I don't do DMs over Discord -- PM me on the forums regarding inquiries.
AlliedModders Releases / Github / TF2 Server / Donate (BTC / BCH / coffee)
nosoop is offline
walabulu4
Junior Member
Join Date: Sep 2019
Old 10-04-2019 , 11:52   Re: Spawn a rocket on button press
Reply With Quote #3

Quote:
Originally Posted by nosoop View Post
Is this for TF2? Since it looks like you're up for learning how to do it, here's some steps you can follow:
  1. Add a command listener to the "voicemenu" command and detect the "MEDIC!" call. You can use this snippet (ported to new syntax, ideally). Make sure it works by displaying some messages with PrintToChat or PrintToServer before moving on.
  2. Determine the position to spawn your rocket (likely with GetClientEyePosition and GetClientEyeAngles), then spawn your rocket. This snippet should be fine, though it's also in old syntax.
  3. Set up a cooldown. Create a float array for your players (size MAXPLAYERS + 1), then when you need to update your cooldown, set it to GetGameTime() + your_cooldown_amount. You can check if the cooldown has passed if GetGameTime() is larger than the array entry. Don't forget to zero out the time in an OnClientPutInServer() forward.

Thank you! I shall give this a shot. I am a little unsure of new syntax vs old, but im sure some trial and error will solve that
walabulu4 is offline
PC Gamer
Veteran Member
Join Date: Mar 2014
Old 10-04-2019 , 15:46   Re: Spawn a rocket on button press
Reply With Quote #4

Since Halloween approaches you may also consider spells instead of rockets. I have a few giants/bosses like Merasmus the Wizard that launch spells when you press certain buttons.
PC Gamer is offline
PC Gamer
Veteran Member
Join Date: Mar 2014
Old 10-05-2019 , 14:59   Re: Spawn a rocket on button press
Reply With Quote #5

I managed to use these tips to spawn a rocket when a player calls for a medic. However, it causes an explosion at the client in addition to firing the rocket.

How can I fire the rocket without causing an explosion at the client?

Code:
Code:
#pragma semicolon 1
#include <TF2_stocks> 

#define RSOUND "weapons/rocket_blackbox_shoot.wav"

public Plugin myinfo = 
{
	name = "The Medic Rocket",
	author = "PC Gamer",
	description = "Shoots Rocket when you call for Medic",
	version = "PLUGIN_VERSION 1.0",
	url = "www.sourcemod.com"	
}

public OnPluginStart()
{ 
	AddNormalSoundHook(GamerSH);
}

public OnMapStart()
{
	PrecacheSound(RSOUND, true);
}

public Action:GamerSH(clients[64], &numClients, String:sample[PLATFORM_MAX_PATH], &entity, &channel, &Float:volume, &level, &pitch, &flags)
{
	if (!IsValidClient(entity)) return Plugin_Continue;
	if (StrContains(sample, "_medic0", false) != -1)
	{
		sample = RSOUND;

		decl Float:ang[3];
		decl Float:pos[3];
		GetClientEyePosition(entity, pos);
		GetClientEyeAngles(entity, ang);		
		new RTeam = GetClientTeam(entity);
		FireTeamRocket(pos, ang, entity, RTeam);

		return Plugin_Changed;
	}
	return Plugin_Changed;
}

stock FireTeamRocket(Float:vPos[3], Float:vAng[3], iOwner = 0, iTeam = 0, Float:flSpeed = 1100.0, Float:flDamage = 90.0, bool:bCrit = false, iWeapon = -1)
{
	new iRocket = CreateEntityByName("tf_projectile_rocket");
	if (IsValidEntity(iRocket))
	{
		decl Float:vVel[3]; // Determine velocity based on given speed/angle
		GetAngleVectors(vAng, vVel, NULL_VECTOR, NULL_VECTOR);
		ScaleVector(vVel, flSpeed);
		
		SetEntProp(iRocket, Prop_Send, "m_bCritical", bCrit);

		SetRocketDamage(iRocket, flDamage);

		SetEntProp(iRocket, Prop_Send, "m_nSkin", (0, iTeam - 2)); // 0 = RED 1 = BLU
		SetEntProp(iRocket, Prop_Send, "m_iTeamNum", iTeam, 1);
		SetVariantInt(iTeam);
		AcceptEntityInput(iRocket, "TeamNum");
		SetVariantInt(iTeam);
		AcceptEntityInput(iRocket, "SetTeam");

		if (iOwner != -1)
		{
			SetEntPropEnt(iRocket, Prop_Send, "m_hOwnerEntity", iOwner);
		}
		
		TeleportEntity(iRocket, vPos, vAng, vVel);
		DispatchSpawn(iRocket);
		
		if (iWeapon != -1)
		{
			SetEntPropEnt(iRocket, Prop_Send, "m_hOriginalLauncher", iWeapon); // GetEntPropEnt(baseRocket, Prop_Send, "m_hOriginalLauncher")
			SetEntPropEnt(iRocket, Prop_Send, "m_hLauncher", iWeapon); // GetEntPropEnt(baseRocket, Prop_Send, "m_hLauncher")
		}
		
		return iRocket;
	}
	return -1;
}

static s_iRocketDmgOffset = -1;

stock SetRocketDamage(iRocket, Float:flDamage)
{
	if (s_iRocketDmgOffset == -1)
	{
		s_iRocketDmgOffset = FindSendPropInfo("CTFProjectile_Rocket", "m_iDeflected") + 4; // Credit to voogru
	}
	SetEntDataFloat(iRocket, s_iRocketDmgOffset, flDamage, true);
}

stock Float:GetRocketDamage(iRocket)
{
	if (s_iRocketDmgOffset == -1)
	{
		s_iRocketDmgOffset = FindSendPropOffs("CTFProjectile_Rocket", "m_iDeflected") + 4; // Credit to voogru
	}
	return GetEntDataFloat(iRocket, s_iRocketDmgOffset);
}  

stock bool:IsValidClient(client)
{
	if (client <= 0) return false;
	if (client > MaxClients) return false;
	return IsClientInGame(client);
}
PC Gamer is offline
walabulu4
Junior Member
Join Date: Sep 2019
Old 10-09-2019 , 23:49   Re: Spawn a rocket on button press
Reply With Quote #6

Damn, I didn't even have to try. I typed it line by line hoping that helped me learn thank you so so much!!
walabulu4 is offline
walabulu4
Junior Member
Join Date: Sep 2019
Old 10-10-2019 , 01:34   Re: Spawn a rocket on button press
Reply With Quote #7

Quote:
Originally Posted by PC Gamer View Post
I managed to use these tips to spawn a rocket when a player calls for a medic. However, it causes an explosion at the client in addition to firing the rocket.

How can I fire the rocket without causing an explosion at the client?

Code:
Code:
#pragma semicolon 1
#include <TF2_stocks> 

#define RSOUND "weapons/rocket_blackbox_shoot.wav"

public Plugin myinfo = 
{
	name = "The Medic Rocket",
	author = "PC Gamer",
	description = "Shoots Rocket when you call for Medic",
	version = "PLUGIN_VERSION 1.0",
	url = "www.sourcemod.com"	
}

public OnPluginStart()
{ 
	AddNormalSoundHook(GamerSH);
}

public OnMapStart()
{
	PrecacheSound(RSOUND, true);
}

public Action:GamerSH(clients[64], &numClients, String:sample[PLATFORM_MAX_PATH], &entity, &channel, &Float:volume, &level, &pitch, &flags)
{
	if (!IsValidClient(entity)) return Plugin_Continue;
	if (StrContains(sample, "_medic0", false) != -1)
	{
		sample = RSOUND;

		decl Float:ang[3];
		decl Float:pos[3];
		GetClientEyePosition(entity, pos);
		GetClientEyeAngles(entity, ang);		
		new RTeam = GetClientTeam(entity);
		FireTeamRocket(pos, ang, entity, RTeam);

		return Plugin_Changed;
	}
	return Plugin_Changed;
}

stock FireTeamRocket(Float:vPos[3], Float:vAng[3], iOwner = 0, iTeam = 0, Float:flSpeed = 1100.0, Float:flDamage = 90.0, bool:bCrit = false, iWeapon = -1)
{
	new iRocket = CreateEntityByName("tf_projectile_rocket");
	if (IsValidEntity(iRocket))
	{
		decl Float:vVel[3]; // Determine velocity based on given speed/angle
		GetAngleVectors(vAng, vVel, NULL_VECTOR, NULL_VECTOR);
		ScaleVector(vVel, flSpeed);
		
		SetEntProp(iRocket, Prop_Send, "m_bCritical", bCrit);

		SetRocketDamage(iRocket, flDamage);

		SetEntProp(iRocket, Prop_Send, "m_nSkin", (0, iTeam - 2)); // 0 = RED 1 = BLU
		SetEntProp(iRocket, Prop_Send, "m_iTeamNum", iTeam, 1);
		SetVariantInt(iTeam);
		AcceptEntityInput(iRocket, "TeamNum");
		SetVariantInt(iTeam);
		AcceptEntityInput(iRocket, "SetTeam");

		if (iOwner != -1)
		{
			SetEntPropEnt(iRocket, Prop_Send, "m_hOwnerEntity", iOwner);
		}
		
		TeleportEntity(iRocket, vPos, vAng, vVel);
		DispatchSpawn(iRocket);
		
		if (iWeapon != -1)
		{
			SetEntPropEnt(iRocket, Prop_Send, "m_hOriginalLauncher", iWeapon); // GetEntPropEnt(baseRocket, Prop_Send, "m_hOriginalLauncher")
			SetEntPropEnt(iRocket, Prop_Send, "m_hLauncher", iWeapon); // GetEntPropEnt(baseRocket, Prop_Send, "m_hLauncher")
		}
		
		return iRocket;
	}
	return -1;
}

static s_iRocketDmgOffset = -1;

stock SetRocketDamage(iRocket, Float:flDamage)
{
	if (s_iRocketDmgOffset == -1)
	{
		s_iRocketDmgOffset = FindSendPropInfo("CTFProjectile_Rocket", "m_iDeflected") + 4; // Credit to voogru
	}
	SetEntDataFloat(iRocket, s_iRocketDmgOffset, flDamage, true);
}

stock Float:GetRocketDamage(iRocket)
{
	if (s_iRocketDmgOffset == -1)
	{
		s_iRocketDmgOffset = FindSendPropOffs("CTFProjectile_Rocket", "m_iDeflected") + 4; // Credit to voogru
	}
	return GetEntDataFloat(iRocket, s_iRocketDmgOffset);
}  

stock bool:IsValidClient(client)
{
	if (client <= 0) return false;
	if (client > MaxClients) return false;
	return IsClientInGame(client);
}
On messing arround with it further, when I put a debug PrintToServer in the FireTeamRocket Function it prints like 5 or 6 times when I hit E. I wonder if that is causing the issue?

EDIT: I am dumb, I was testing with bots and each bot caused an additional print string to print. After kicking them the script seems to work mostly fine. I don't get hurt by an explosion before the rocket hits something.

Last edited by walabulu4; 10-10-2019 at 01:39.
walabulu4 is offline
PC Gamer
Veteran Member
Join Date: Mar 2014
Old 10-10-2019 , 10:21   Re: Spawn a rocket on button press
Reply With Quote #8

walabulu4, I think you may have discovered the issue with multiple rockets. My guess is that the key being held down fires multiple times a second. Adding a cooldown to the key press will likely fix the problem.
PC Gamer is offline
PC Gamer
Veteran Member
Join Date: Mar 2014
Old 10-10-2019 , 11:03   Re: Spawn a rocket on button press
Reply With Quote #9

Adding a cooldown to the script fixed the problem. I believe you can mark this topic solved. Big thanks to nosoop for the code snippets and his coding tips.

Code:
#pragma semicolon 1
#include <TF2_stocks> 

#define RSOUND "weapons/rocket_blackbox_shoot.wav"

new bool:g_wait[MAXPLAYERS + 1]; 

public Plugin myinfo = 
{
	name = "The Medic Rocket",
	author = "PC Gamer",
	description = "Shoots Rocket when you call for Medic",
	version = "PLUGIN_VERSION 1.1",
	url = "www.sourcemod.com"	
}

public OnPluginStart()
{ 
	AddNormalSoundHook(GamerSH);
}

public OnMapStart()
{
	PrecacheSound(RSOUND, true);
}

public Action:GamerSH(clients[64], &numClients, String:sample[PLATFORM_MAX_PATH], &entity, &channel, &Float:volume, &level, &pitch, &flags)
{
	if (!IsValidClient(entity)) return Plugin_Continue;
	if (g_wait[entity] == true) return Plugin_Continue;
	if (StrContains(sample, "_medic0", false) != -1)
	{
		sample = RSOUND;

		decl Float:ang[3];
		decl Float:pos[3];
		GetClientEyePosition(entity, pos);
		GetClientEyeAngles(entity, ang);		
		new RTeam = GetClientTeam(entity);
		FireTeamRocket(pos, ang, entity, RTeam);
		g_wait[entity] = true;
		CreateTimer(0.1, Waiting, entity);		

		return Plugin_Changed;
	}
	return Plugin_Changed;
}

stock FireTeamRocket(Float:vPos[3], Float:vAng[3], iOwner = 0, iTeam = 0, Float:flSpeed = 1100.0, Float:flDamage = 90.0, bool:bCrit = false, iWeapon = -1)
{
	new iRocket = CreateEntityByName("tf_projectile_rocket");
	if (IsValidEntity(iRocket))
	{
		decl Float:vVel[3]; // Determine velocity based on given speed/angle
		GetAngleVectors(vAng, vVel, NULL_VECTOR, NULL_VECTOR);
		ScaleVector(vVel, flSpeed);
		
		SetEntProp(iRocket, Prop_Send, "m_bCritical", bCrit);

		SetRocketDamage(iRocket, flDamage);

		SetEntProp(iRocket, Prop_Send, "m_nSkin", (0, iTeam - 2)); // 0 = RED 1 = BLU
		SetEntProp(iRocket, Prop_Send, "m_iTeamNum", iTeam, 1);
		SetVariantInt(iTeam);
		AcceptEntityInput(iRocket, "TeamNum");
		SetVariantInt(iTeam);
		AcceptEntityInput(iRocket, "SetTeam");

		if (iOwner != -1)
		{
			SetEntPropEnt(iRocket, Prop_Send, "m_hOwnerEntity", iOwner);
		}
		
		TeleportEntity(iRocket, vPos, vAng, vVel);
		DispatchSpawn(iRocket);
		
		if (iWeapon != -1)
		{
			SetEntPropEnt(iRocket, Prop_Send, "m_hOriginalLauncher", iWeapon); // GetEntPropEnt(baseRocket, Prop_Send, "m_hOriginalLauncher")
			SetEntPropEnt(iRocket, Prop_Send, "m_hLauncher", iWeapon); // GetEntPropEnt(baseRocket, Prop_Send, "m_hLauncher")
		}
		
		return iRocket;
	}
	return -1;
}

static s_iRocketDmgOffset = -1;

stock SetRocketDamage(iRocket, Float:flDamage)
{
	if (s_iRocketDmgOffset == -1)
	{
		s_iRocketDmgOffset = FindSendPropInfo("CTFProjectile_Rocket", "m_iDeflected") + 4; // Credit to voogru
	}
	SetEntDataFloat(iRocket, s_iRocketDmgOffset, flDamage, true);
}

stock Float:GetRocketDamage(iRocket)
{
	if (s_iRocketDmgOffset == -1)
	{
		s_iRocketDmgOffset = FindSendPropOffs("CTFProjectile_Rocket", "m_iDeflected") + 4; // Credit to voogru
	}
	return GetEntDataFloat(iRocket, s_iRocketDmgOffset);
}  

stock bool:IsValidClient(client)
{
	if (client <= 0) return false;
	if (client > MaxClients) return false;
	return IsClientInGame(client);
}

public Action:Waiting(Handle:timer, any:client) 
{
	g_wait[client] = false;
}
PC Gamer is offline
walabulu4
Junior Member
Join Date: Sep 2019
Old 10-17-2019 , 14:00   Re: Spawn a rocket on button press
Reply With Quote #10

Not sure how to mark the thread as solved. But thank you very much! I was struggling to try and add a cooldown. but slowly getting better at scripting.
walabulu4 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 12:13.


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