Skip to main content

Combat tasks

Making an NPC fight in GTA V requires two things: an appropriate weapon in their hands, and a combat task directing their aggression toward a target. Without both, an armed NPC may just stand idle or flee when shot at.

Arming an NPC

To equip a character with a weapon and ammunition, use the Weapons.Give method:

using GTA;

public void EquipBodyguard(Ped guard)
{
// Give a pistol with 100 rounds, equip immediately, loaded
guard.Weapons.Give(WeaponHash.Pistol, 100, true, true);

// Tune combat capability
guard.Armor = 100;
guard.Accuracy = 60; // 0 to 100 percent accuracy
}

Targeting a specific aggressor

The most reliable way to trigger combat is directing the NPC toward an explicit, known enemy:

guard.Task.Combat(aggressor, TaskCombatFlags.None, TaskThreatResponseFlags.None);

This method commands the native combat AI to take cover, aim, fire, advance, and flank the specified enemy entity until that entity dies or the task is cleared.

Avoid obsolete combat methods

In older tutorials and forum posts, you will often see:

// OBSOLETE in modern SHVDN: do not use
guard.Task.FightAgainstHatedTargets(50f);

FightAgainstHatedTargets is deprecated in modern ScriptHookVDotNet3. It relies on ambient threat scans that frequently fail to identify enemies in dynamic firefights.

Instead, use one of two modern approaches:

  1. Explicit target combat: guard.Task.Combat(aggressor, ...) when your script knows who the attacker is (recommended for bodyguards and missions).
  2. Modern area scan: guard.Task.CombatHatedTargetsAroundPedTimed(player, 50f, 10000) when relying on relationship groups.

The BlockPermanentEvents flag

Ambient NPCs in Los Santos are controlled by a global ambient director. If a gun goes off, normal pedestrians scream and run away.

If you are creating a scripted bodyguard, security guard, or gang member who must follow your orders rather than panic, lock their decision making:

// Prevents ambient events (screams, gunshots) from overriding scripted tasks
guard.BlockPermanentEvents = true;

This single line is what separates a reliable scripted ally from a character who flees the moment a siren sounds.

Next, we look at factions and hostility: how relationship groups define allies, neutrals, and enemies.