Return C4 when planted near S&D site

Hi!
I’m trying to make a script where if you plant C4 near a search & destroy bomb site, it will return the C4 to you. (As a server-side only mod on a server).

I’ve figured out where s&d sets level.bombZones and getting those locations, as well as calculating distance between c4 & bombzones (I think).

I’ve figured out that once the c4 lands, it notifies the “activated” event. I can use that to then calculate the distance to each bombZone, and if it’s less than a certain amount, can delete the c4.

But what I can’t figure out is the actual c4 ammunition part, as it seems to be duplicated it _c4.gsc & _weapons.gsc & _detonategrenades.gsc.

I’m unsure which to use, as it looks like the c4_mp is only in _weapons.gsc, but I cannot find where it sets/controls the player’s c4 ammo in that file.

Basically, I’m unsure which is actually the c4 code used for multiplayer servers, or if any are singleplayer only or something like that.

I’m new to modding cod4, so I’m unfamiliar with the specifics used here.

Hey welcome aboard junior coder!

What you are looking for is the c4 entity it seems, from there you can manipulate and track:

self waittill( "grenade_fire", c4, weapname );
if ( weapname == "c4" || weapname == "c4_mp" ) {
    c4_entity = c4;
}

From there you can do what you want with c4_entity.

What you seem to want is something like:

if(distance2d(c4_entity.origin, bombzone) > maxdistance) 
    c4_entity delete();

Anyways, I’m sure that’s enough for you to figure it out… good luck.

Hello, thanks for the help!

This is what I have made:

    c4 thread maps\mp\gametypes\_shellshock::c4_earthQuake();
    c4 thread c4Activate();
+   c4 thread c4_return_if_too_close_to_sd_bomb_site( self, weapname );
c4_return_if_too_close_to_sd_bomb_site( player, weapname )
{
	self endon("death");
	self endon( "disconnect" );	
	self endon( "detonated" );
	level endon( "game_ended" );

	if( !isDefined( self.owner ) )
		return;

	if( !isDefined( level.bombZones ) )
		return;

	minDist = getDvarInt("scr_sd_c4_min_distance");

	if( minDist <= 0 )
		return;


	self waittill( "activated" );

	// give small time window for instant-explode usage
	wait 0.5;

	for(i = 0; i < level.bombZones.size; i++)
	{
		if( !isDefined( level.bombZones[i] ) )
			continue;

		dist = distance2D( self.origin, level.bombZones[i].curOrigin );
		// player iprintlnbold( "bomb zone dist: " + dist );

		if( dist < minDist )
		{
			// return c4 to player
			ammoCount = player getAmmoCount( weapname );
			player SetWeaponAmmoClip( weapname, ammoCount + 1 );
			player iprintlnbold( "^1C4 is not allowed that close to a bomb site!" );
			self delete();
			return;
		}
	}
}

It works up until:

ammoCount = self getammocount( weapname );

so I believe I am not using the right functions to modify the amount of c4 the player has. I’ve tried many of the different functions to do with ammo also used internally in the file, but none worked. I’m obviously missing something, I will continue investigating onwards!

Commenting out the lines about the ammo, the rest of it works! It deletes the C4 and tells the player the warning.

Edit: Got it working, and have edited the code above to what I’ve got now!
Edit 2: Figured out colouring text!

If you could aid with 3 last things I am wondering about, that would be appreciated:
1. What are the correct functions to modify c4 ammo count?
2. Do I need to reduce / clean the player.c4array?
3. How can I change the colour of the messages sent to the player?

From what I can see in the code, it creates triggers and by deleting the entity that trigger remains. Try doing a notify on the c4 before deleting.

...
self notify("death");
self delete();
...

That’s a good point. However, notifying death while listening to death stops it before deleting, which it should probably endon death.
So this is the final script I have come up with:

c4_return_if_too_close_to_sd_bomb_site( player, weapname )
{
	self endon( "disconnect" );	
	self endon( "detonated" );
	level endon( "game_ended" );

	if( !isDefined( self.owner ) )
		return;

	if( !isDefined( level.bombZones ) )
		return;

	minDist = getDvarInt("scr_sd_c4_min_distance");

	if( minDist <= 0 )
		return;


	self waittill( "activated" );

	// give small time window for instant-explode usage
	wait 0.5;

	for(i = 0; i < level.bombZones.size; i++)
	{
		if( !isDefined( level.bombZones[i] ) )
			continue;

		dist = distance2D( self.origin, level.bombZones[i].curOrigin );
		// player iprintlnbold( "bomb zone dist: " + dist );

		if( dist < minDist )
		{
			// return c4 to player
			ammoCount = player getAmmoCount( weapname );
			player SetWeaponAmmoClip( weapname, ammoCount + 1 );
			player iprintlnbold( "^1C4 is not allowed that close to a bomb site!" );
			self notify("death");
			self delete();
			return;
		}
	}
}

Thanks for your help!

1 Like