Activating and Fixing AI In Coop Games: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
m (and another one)
No edit summary
Line 3: Line 3:
Howdy!  
Howdy!  


Many people asked me why their NPCs were not moving or attacking the player in their HL2DM Coop mod.
This article is an updated version of the previous tutorial '''Activating AI In Coop Games'''.
Well, NPCs do not attack you or whatever because Half-Life 2: Deathmatch does not initially include the NPCs' relation ship table. Thus I am going to teach you how to lead them to do something more decent than patrolling around their spawn-point.
Though the previous article allowed you to enable AI in multiplayer games, humanoid NPCs like ''Combine Soldiers'' could not attack the player. It is annoying, isn't it? Well, I think this is time to get over it!


Before we go on, I would like to thank Garry Newman, BunkMug & FoxFire - for their contributions to the A.I problem - and some other people on the forums who helped me to figure out that crazy stuff.
I hope the article will help!




Line 89: Line 91:
</pre>
</pre>


=Import skills data=
 
Few people noticed that NPCs were not causing any damage to the player and that they could die instantly.
=Making Humanoid NPCs Shoot=
This issue is simply caused by the fact the file '''skill.cfg''' is missing from the ''"\cfg"'' directory in the mod-dir.
==Weapons Animations Code==
To fix it, create a new text file with Notepad, put the code bellow in it, then rename the file to '''skill.cfg'''.
First, find each weapon SP code ( located in the \dlls\hl2_dll\ folder ), then move all the animations declarations located in the SP-acttable_t function to the HL2MP-acttable_t structure. See example bellow:


<pre>
<pre>
// ===========
acttable_t CWeaponSMG1::m_acttable[] =  
// NPCs
{
// ============
//HL2DM ANIMATIONS LIST START
// Barnacle
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_SMG1, false },
sk_barnacle_health "35"
( ... )
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SMG1, false },
//HL2MP ANIMATIONS LIST END


// Barney
//HL2SP ANIMATIONS LIST START
sk_barney_health "35"
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SMG1, true },
{ ACT_RELOAD, ACT_RELOAD_SMG1, true },
{ ACT_IDLE, ACT_IDLE_SMG1, true },
(...)
{ ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_SMG1, true },
//HL2SP ANIMATIONS LIST END


// Bullseye
}
sk_bullseye_health "35"
</pre>


//Bullsquid
==Weapons Animations Code==
sk_bullsquid_health "40"
sk_bullsquid_dmg_bite  "15"
sk_bullsquid_dmg_whip  "25"
sk_bullsquid_dmg_spit "10"


// Citizen
sk_citizen_health "40"


// Combine Soldier
sk_combine_s_health "50"
sk_combine_s_kick "10"


// Combine Guard
sk_combine_guard_health "70"
sk_combine_guard_kick "15"


// strider
sk_strider_health "350"
sk_strider_num_missiles1 "5"
sk_strider_num_missiles2 "7"
sk_strider_num_missiles3 "7"


// Headcrab
==Other Weapons Modifications==
sk_headcrab_health "10"
Now you have to edit each weapon code by adding a few lines of code in their class definition.
sk_headcrab_melee_dmg "5"
In each weapon class, add those declarations ( server side only ):


// Fast Headcrab
<pre>
sk_headcrab_fast_health "10"
#ifndef CLIENT_DLL
//ALLOW NPCS TO USE THE WEAPON TO SHOOT THEIR ENNEMIES
int CapabilitiesGet( void ) { return bits_CAP_WEAPON_RANGE_ATTACK1; }
//HANDLES AI'S ACTIVITIES
void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator );
#endif
</pre>


// Poison Headcrab
'''NOTICE:''' You will find the ''Operator_HandleAnimEvent()'' function body in the SP-code of the weapon. Thus, do not forget to copy/paste it to avoid compiling errors!
sk_headcrab_poison_health "35"


// Houndeye
sk_houndeye_health "80"
sk_houndeye_dmg_blast "15"


// Manhack
==Garry Newman's suggestion==
sk_manhack_health "25"
Garry Newman suggested on forums to modify the ''SetActivity()'' function code.
sk_manhack_melee_dmg "20"
Thus, in the '''basecombatweapon_shared.cpp''' file, find the ''SetActivity()'' function, and then, after Adrian's comment:
<pre>
//Adrian: Oh man...
</pre>


// Metropolice
replace
sk_metropolice_health "40"
sk_metropolice_stitch_reaction "1.0"
sk_metropolice_stitch_tight_hitcount "2"
sk_metropolice_stitch_at_hitcount "1"
sk_metropolice_stitch_behind_hitcount "3"
sk_metropolice_stitch_along_hitcount "2"


// Rollermine
<pre>
sk_rollermine_shock "10"
#if !defined( CLIENT_DLL ) && defined( HL2MP )
sk_rollermine_stun_delay "3"
SetModel( GetWorldModel() );
sk_rollermine_vehicle_intercept "1"
#endif
</pre>


// Scanner (City)
to
sk_scanner_health "30"
sk_scanner_dmg_dive "25"


// Stalker
sk_stalker_health "50"
sk_stalker_melee_dmg "5"


// Vortigaunt
<pre>
sk_vortigaunt_health "100"
if ( GetOwner()->IsPlayer() )
sk_vortigaunt_dmg_claw "10"
SetModel( GetWorldModel() );
sk_vortigaunt_dmg_rake "25"
</pre>
sk_vortigaunt_dmg_zap "20"
sk_vortigaunt_armor_charge "30"


// Zombie
sk_zombie_health "50"
sk_zombie_dmg_one_slash "10"
sk_zombie_dmg_both_slash "25"


// Poison Zombie
Proceed similarily after the other comment, so you replace:
sk_zombie_poison_health "175"
sk_zombie_poison_dmg_spit "20"


//Antlion
<pre>
sk_antlion_health "30"
//Adrian: Oh man again...
sk_antlion_swipe_damage "5"
#if !defined( CLIENT_DLL ) && defined( HL2MP )
sk_antlion_jump_damage "5"
SetModel( GetViewModel() );
#endif
</pre>


//Antlion Guard
to
sk_antlionguard_health "500"
sk_antlionguard_dmg_charge "20"
sk_antlionguard_dmg_shove "10"


//Antlion Grub
<pre>
//sk_antliongrub_health "5"
//Adrian: Oh man again...
if ( GetOwner()->IsPlayer() )
SetModel( GetViewModel() );
</pre>


//Ichthyosaur
Well, I don't now if that code fixes anything, I have not tried yet. I hope you will give me feedback about that piece of code.
sk_ichthyosaur_health "200"
sk_ichthyosaur_melee_dmg "8"


// Combine Gunship
sk_gunship_burst_size "15"
sk_gunship_health_increments "5"
sk_npc_dmg_gunship "40"
sk_npc_dmg_gunship_to_plr "3"


// Combine Helicopter
==Ammotypes==
sk_npc_dmg_helicopter "6"
Well, if the NPCS kill you instantly - ''it happened to me'' - here's the tip to fix it. In the '''hl2mp_gamerules.cpp''' file, replace the whole ''CAmmoDef *GetAmmoDef()'' function to this:
sk_npc_dmg_helicopter_to_plr "3"
sk_helicopter_grenadedamage "30"
sk_helicopter_grenaderadius "275"
sk_helicopter_grenadeforce "55000"


// Combine Dropship
<pre>
sk_npc_dmg_dropship "2"
CAmmoDef *GetAmmoDef()
{
static CAmmoDef def;
static bool bInitted = false;
if ( !bInitted )
{
bInitted = true;


// Combine APC
//THOMAS: HL2SP DEFINITIONS
sk_apc_health "750"
def.AddAmmoType("AR2", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_ar2", "sk_npc_dmg_ar2", "sk_max_ar2", BULLET_IMPULSE(200, 1225), 0 );
def.AddAmmoType("AlyxGun", DMG_BULLET, TRACER_LINE, "sk_plr_dmg_alyxgun", "sk_npc_dmg_alyxgun", "sk_max_alyxgun", BULLET_IMPULSE(200, 1225), 0 );
def.AddAmmoType("Pistol", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_pistol", "sk_npc_dmg_pistol", "sk_max_pistol", BULLET_IMPULSE(200, 1225), 0 );
def.AddAmmoType("SMG1", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_smg1", "sk_npc_dmg_smg1", "sk_max_smg1", BULLET_IMPULSE(200, 1225), 0 );
def.AddAmmoType("357", DMG_BULLET, TRACER_LINE_AND_WHIZ, " sk_plr_dmg_357", "sk_npc_dmg_357", "sk_max_357", BULLET_IMPULSE(800, 5000), 0 );
def.AddAmmoType("XBowBolt", DMG_BULLET, TRACER_LINE, "sk_plr_dmg_crossbow", "sk_npc_dmg_crossbow", "sk_max_crossbow", BULLET_IMPULSE(800, 8000), 0 );


def.AddAmmoType("Buckshot", DMG_BULLET | DMG_BUCKSHOT, TRACER_LINE, "sk_plr_dmg_buckshot", "sk_npc_dmg_buckshot", "sk_max_buckshot", BULLET_IMPULSE(400, 1200), 0 );
def.AddAmmoType("RPG_Round", DMG_BURN, TRACER_NONE, "sk_plr_dmg_rpg_round", "sk_npc_dmg_rpg_round", "sk_max_rpg_round", 0, 0 );
def.AddAmmoType("SMG1_Grenade", DMG_BURN, TRACER_NONE, "sk_plr_dmg_smg1_grenade", "sk_npc_dmg_smg1_grenade", "sk_max_smg1_grenade", 0, 0 );
def.AddAmmoType("Grenade", DMG_BURN, TRACER_NONE, "sk_plr_dmg_grenade", "sk_npc_dmg_grenade", "sk_max_grenade", 0, 0);
def.AddAmmoType("Thumper", DMG_SONIC, TRACER_NONE, 10, 10, 2, 0, 0 );
def.AddAmmoType("Gravity", DMG_CLUB, TRACER_NONE, 0, 0, 8, 0, 0 );
def.AddAmmoType("Battery", DMG_CLUB, TRACER_NONE, NULL, NULL, NULL, 0, 0 );
def.AddAmmoType("GaussEnergy", DMG_SHOCK, TRACER_NONE, "sk_jeep_gauss_damage", "sk_jeep_gauss_damage", "sk_max_gauss_round", BULLET_IMPULSE(650, 8000), 0 ); // hit like a 10kg weight at 400 in/s
def.AddAmmoType("CombineCannon", DMG_BULLET, TRACER_LINE, "sk_npc_dmg_gunship_to_plr", "sk_npc_dmg_gunship", NULL, 1.5 * 750 * 12, 0 ); // hit like a 1.5kg weight at 750 ft/s
def.AddAmmoType("AirboatGun", DMG_AIRBOAT, TRACER_LINE, "sk_plr_dmg_airboat", "sk_npc_dmg_airboat", NULL, BULLET_IMPULSE(10, 600), 0 );
def.AddAmmoType("StriderMinigun", DMG_BULLET, TRACER_LINE, 5, 5, 15, 1.0 * 750 * 12, AMMO_FORCE_DROP_IF_CARRIED ); // hit like a 1.0kg weight at 750 ft/s
def.AddAmmoType("HelicopterGun", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_npc_dmg_helicopter_to_plr", "sk_npc_dmg_helicopter", "sk_max_smg1", BULLET_IMPULSE(400, 1225), AMMO_FORCE_DROP_IF_CARRIED | AMMO_INTERPRET_PLRDAMAGE_AS_DAMAGE_TO_PLAYER );
def.AddAmmoType("AR2AltFire", DMG_DISSOLVE, TRACER_NONE, 0, 0, "sk_max_ar2_altfire", 0, 0 );
//***
}


// =================
return &def;
//  WEAPONS
}
// =================
</pre>


sk_plr_dmg_ar2 "8"
sk_npc_dmg_ar2 "3"
sk_max_ar2 "60"
sk_max_ar2_altfire "3"


sk_plr_dmg_alyxgun "5"
sk_npc_dmg_alyxgun "3"
sk_max_alyxgun "150"


sk_plr_dmg_pistol "5"
sk_npc_dmg_pistol "3"
sk_max_pistol "150"


sk_plr_dmg_smg1 "4"
sk_npc_dmg_smg1 "3"
sk_max_smg1 "225"


sk_plr_dmg_buckshot "8"
sk_npc_dmg_buckshot "3"
sk_max_buckshot "30"


sk_max_pulsemg "200"
=Let's Finish=
 
==Import skills data==
sk_plr_dmg_rpg_round "100"
Few people noticed that NPCs were not causing any damage to the player and that they could die instantly.
sk_npc_dmg_rpg_round "50"
This issue is simply caused by the fact the file '''skill.cfg''' is missing from the ''"\cfg"'' directory in the mod-dir.
sk_max_rpg_round "3"
To fix it, get the '''skill.cfg''' file located in the Half-Lfe 2 folder.
 
sk_plr_dmg_smg1_grenade "100"
sk_npc_dmg_smg1_grenade "50"
sk_max_smg1_grenade "3"
sk_smg1_grenade_radius "250"
 
//sk_plr_dmg_gauss "25"
//sk_plr_max_dmg_gauss "30"
 
sk_plr_dmg_sniper_round "13"
sk_npc_dmg_sniper_round "100"
sk_max_sniper_round "60"
 
sk_plr_dmg_357 "40"
sk_npc_dmg_357 "30"
sk_max_357 "12"
 
sk_plr_dmg_crossbow "100"
sk_npc_dmg_crossbow "10"
sk_max_crossbow "10"
 
sk_plr_dmg_airboat "3"
sk_npc_dmg_airboat "3"
 
//sk_dmg_sniper_penetrate_plr "10"
//sk_dmg_sniper_penetrate_npc "100"
 
sk_plr_dmg_grenade "150"
sk_npc_dmg_grenade "75"
sk_max_grenade "5"
 
sk_plr_dmg_crowbar "13"
sk_npc_dmg_crowbar "5"
 
sk_plr_dmg_stunstick "10"
sk_npc_dmg_stunstick "40" // Kill a citizen in one hit
 
//sk_plr_dmg_satchel "150"
//sk_npc_dmg_satchel "75"
//sk_satchel_radius "150"
 
// Mortar Synth projectile
//sk_dmg_energy_grenade "2"
//sk_energy_grenade_radius "100"
 
sk_dmg_homer_grenade "20"
sk_homer_grenade_radius "100"


// Bullsquid spit
==Models Animations==
sk_dmg_spit_grenade "30"
You have to replace the HL2DM NPCS animations by the HL2 ones. Indeed HL2DM overrides the NPCs animations - ''used for the player models'' - so it breaks the AI. Thus, you have to use other models files for the players. You can hexedit the HL2DM player models & animations to make it tight. You will also have to put the HL2 original models in your ''\models'' folder.
sk_spit_grenade_radius "120"
Finally, do not forget to modify the code related to the player models list in the '''hl2mp_player.cpp''' file.


//sk_plr_dmg_tripmine "150"
Well, I don't want you to waste time hex-editing the model files, so I borrowed Garry's models, you can downoad the whoe package here: [http://dolphineye.ifrance.com/aifix.rar aifix.rar ]
//sk_npc_dmg_tripmine "125"
//sk_tripmine_radius "200"


sk_plr_dmg_fraggrenade "125"
sk_npc_dmg_fraggrenade "75"
sk_fraggrenade_radius "250"


// HEALTH/SUIT CHARGE DISTRIBUTION
sk_suitcharger "75"
sk_suitcharger_citadel "500"
sk_suitcharger_citadel_maxarmor "200"
sk_battery "15"
sk_healthcharger "50"
sk_healthkit "25"
sk_healthvial "10"


// Combine balls
Hope it helps! Happy modding!
sk_combineball_seek_angle "15"
sk_combineball_guidefactor "1.0"


// NPC damage adjusters
sk_npc_head "3"
sk_npc_chest "1"
sk_npc_stomach "1"
sk_npc_arm "1"
sk_npc_leg "1"
// player damage adjusters
sk_player_head "3"
sk_player_chest "1"
sk_player_stomach "1"
sk_player_arm "1"
sk_player_leg "1"
// Allies
sk_ally_regen_time "0.2"
// Jeep
sk_max_gauss_round "30"
</pre>


=Conclusion=
This tutorial should help you to get NPCs working in HL2DM. You could do it manually for each NPC, but I think this should help you not to waste time!


Happy programming!
{{otherlang:en}} {{otherlang:en:fr|Activer IA en Coop}}
{{otherlang:en}} {{otherlang:en:fr|Activer IA en Coop}}

Revision as of 15:31, 17 March 2006

Introduction

Howdy!

This article is an updated version of the previous tutorial Activating AI In Coop Games. Though the previous article allowed you to enable AI in multiplayer games, humanoid NPCs like Combine Soldiers could not attack the player. It is annoying, isn't it? Well, I think this is time to get over it!

Before we go on, I would like to thank Garry Newman, BunkMug & FoxFire - for their contributions to the A.I problem - and some other people on the forums who helped me to figure out that crazy stuff. I hope the article will help!


The Relationship Table

Creating the Table

First of all, we should define the NPCs relationship table. Open the BaseEntity.h file, then in the enum Class_T definition, after the #elif defined( CSTRIKE_DLL ) block, add this:

//***THOMAS*** INITS NPCs' RELATION SHIP TABLE FOR HL2DM
#elif defined ( HL2MP_DLL || HL2MP )
// For CLASSIFY
enum Class_T
{
	CLASS_NONE=0,				
	CLASS_PLAYER,			
	CLASS_PLAYER_ALLY,
	CLASS_PLAYER_ALLY_VITAL,
	CLASS_ANTLION,
	CLASS_BARNACLE,
	CLASS_BULLSEYE,
	CLASS_CITIZEN_PASSIVE,	
	CLASS_CITIZEN_REBEL,
	CLASS_COMBINE,
	CLASS_COMBINE_GUNSHIP,
	CLASS_CONSCRIPT,
	CLASS_HEADCRAB,
	CLASS_MANHACK,
	CLASS_METROPOLICE,		
	CLASS_MILITARY,		
	CLASS_SCANNER,		
	CLASS_STALKER,		
	CLASS_VORTIGAUNT,
	CLASS_ZOMBIE,
	CLASS_PROTOSNIPER,
	CLASS_MISSILE,
	CLASS_FLARE,
	CLASS_EARTH_FAUNA,

	NUM_AI_CLASSES
};
//***

Loading the Table

All right! Now we have to tell the Game Rules to use this relationship table when we start a HL2DM game. Open the hl2mp_gamerules.h file. Under the public: tab, add this:

//***THOMAS*** INITS NPCs' RELATION SHIP TABLE FOR HL2DM
#ifndef CLIENT_DLL 
void InitDefaultAIRelationships( void );
#endif
//***


Now open the hl2mp_gamerules.cpp file. Then, at the very bottom of the file, add this piece of code:

//------------------------------------------------------------------------------
// Purpose : Initialize all default class relationships
// Input   :
// Output  :
//------------------------------------------------------------------------------
//***THOMAS*** INITS NPCs' RELATION SHIP TABLE FOR HL2DM
#ifndef CLIENT_DLL 
void CHL2MPRules::InitDefaultAIRelationships( void )
{
	//Copy contents of the hl2_gamerules InitDefaultAIRelationships to here
}
#endif
//***


Let's finish by adding this in the CHL2MPRules::CHL2MPRules() function:

//***THOMAS*** INITS NPCs' RELATION SHIP TABLE FOR HL2DM
InitDefaultAIRelationships();
//***


Making Humanoid NPCs Shoot

Weapons Animations Code

First, find each weapon SP code ( located in the \dlls\hl2_dll\ folder ), then move all the animations declarations located in the SP-acttable_t function to the HL2MP-acttable_t structure. See example bellow:

acttable_t	CWeaponSMG1::m_acttable[] = 
		{
			//HL2DM ANIMATIONS LIST START
			{ ACT_HL2MP_IDLE,		ACT_HL2MP_IDLE_SMG1,		false },
			( ... )
			{ ACT_RANGE_ATTACK1,		ACT_RANGE_ATTACK_SMG1,		false },
			//HL2MP ANIMATIONS LIST END

			//HL2SP ANIMATIONS LIST START
			{ ACT_RANGE_ATTACK1,		ACT_RANGE_ATTACK_SMG1,		true },
			{ ACT_RELOAD,			ACT_RELOAD_SMG1,		true },
			{ ACT_IDLE,			ACT_IDLE_SMG1,			true },
			(...)
			{ ACT_GESTURE_RELOAD,		ACT_GESTURE_RELOAD_SMG1,	true },
			//HL2SP ANIMATIONS LIST END

		}

Weapons Animations Code

Other Weapons Modifications

Now you have to edit each weapon code by adding a few lines of code in their class definition. In each weapon class, add those declarations ( server side only ):

#ifndef CLIENT_DLL
	//ALLOW NPCS TO USE THE WEAPON TO SHOOT THEIR ENNEMIES
	int CapabilitiesGet( void ) { return bits_CAP_WEAPON_RANGE_ATTACK1; }
	//HANDLES AI'S ACTIVITIES
	void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator );
#endif

NOTICE: You will find the Operator_HandleAnimEvent() function body in the SP-code of the weapon. Thus, do not forget to copy/paste it to avoid compiling errors!


Garry Newman's suggestion

Garry Newman suggested on forums to modify the SetActivity() function code. Thus, in the basecombatweapon_shared.cpp file, find the SetActivity() function, and then, after Adrian's comment:

//Adrian: Oh man...

replace

#if !defined( CLIENT_DLL ) && defined( HL2MP )
	SetModel( GetWorldModel() );
#endif

to


	if ( GetOwner()->IsPlayer() )
		SetModel( GetWorldModel() );


Proceed similarily after the other comment, so you replace:

	//Adrian: Oh man again...
#if !defined( CLIENT_DLL ) && defined( HL2MP )
	SetModel( GetViewModel() );
#endif

to

	//Adrian: Oh man again...
	if ( GetOwner()->IsPlayer() )
		SetModel( GetViewModel() );

Well, I don't now if that code fixes anything, I have not tried yet. I hope you will give me feedback about that piece of code.


Ammotypes

Well, if the NPCS kill you instantly - it happened to me - here's the tip to fix it. In the hl2mp_gamerules.cpp file, replace the whole CAmmoDef *GetAmmoDef() function to this:

CAmmoDef *GetAmmoDef()
	{
		static CAmmoDef def;
		static bool bInitted = false;
	
		if ( !bInitted )
		{
			bInitted = true;

			//THOMAS: HL2SP DEFINITIONS
			def.AddAmmoType("AR2",				DMG_BULLET,					TRACER_LINE_AND_WHIZ,		"sk_plr_dmg_ar2",		"sk_npc_dmg_ar2",			"sk_max_ar2",			BULLET_IMPULSE(200, 1225), 0 );
			def.AddAmmoType("AlyxGun",			DMG_BULLET,					TRACER_LINE,			"sk_plr_dmg_alyxgun",		"sk_npc_dmg_alyxgun",		"sk_max_alyxgun",			BULLET_IMPULSE(200, 1225), 0 );
			def.AddAmmoType("Pistol",			DMG_BULLET,					TRACER_LINE_AND_WHIZ,		"sk_plr_dmg_pistol",		"sk_npc_dmg_pistol",		"sk_max_pistol",			BULLET_IMPULSE(200, 1225), 0 );
			def.AddAmmoType("SMG1",				DMG_BULLET,					TRACER_LINE_AND_WHIZ,		"sk_plr_dmg_smg1",		"sk_npc_dmg_smg1",			"sk_max_smg1",			BULLET_IMPULSE(200, 1225), 0 );
			def.AddAmmoType("357",				DMG_BULLET,					TRACER_LINE_AND_WHIZ,	"	sk_plr_dmg_357",		"sk_npc_dmg_357",			"sk_max_357",			BULLET_IMPULSE(800, 5000), 0 );
			def.AddAmmoType("XBowBolt",			DMG_BULLET,					TRACER_LINE,			"sk_plr_dmg_crossbow",		"sk_npc_dmg_crossbow",		"sk_max_crossbow",			BULLET_IMPULSE(800, 8000), 0 );

			def.AddAmmoType("Buckshot",			DMG_BULLET | DMG_BUCKSHOT,			TRACER_LINE,			"sk_plr_dmg_buckshot",		"sk_npc_dmg_buckshot",		"sk_max_buckshot",			BULLET_IMPULSE(400, 1200), 0 );
			def.AddAmmoType("RPG_Round",			DMG_BURN,					TRACER_NONE,			"sk_plr_dmg_rpg_round",		"sk_npc_dmg_rpg_round",		"sk_max_rpg_round",		0, 0 );
			def.AddAmmoType("SMG1_Grenade",			DMG_BURN,					TRACER_NONE,			"sk_plr_dmg_smg1_grenade",	"sk_npc_dmg_smg1_grenade",	"sk_max_smg1_grenade",	0, 0 );
			def.AddAmmoType("Grenade",			DMG_BURN,					TRACER_NONE,			"sk_plr_dmg_grenade",		"sk_npc_dmg_grenade",		"sk_max_grenade",		0, 0);
			def.AddAmmoType("Thumper",			DMG_SONIC,					TRACER_NONE,			10, 10, 2, 0, 0 );
			def.AddAmmoType("Gravity",			DMG_CLUB,					TRACER_NONE,			0,	0, 8, 0, 0 );
			def.AddAmmoType("Battery",			DMG_CLUB,					TRACER_NONE,			NULL, NULL, NULL, 0, 0 );
			def.AddAmmoType("GaussEnergy",			DMG_SHOCK,					TRACER_NONE,			"sk_jeep_gauss_damage",		"sk_jeep_gauss_damage", "sk_max_gauss_round", BULLET_IMPULSE(650, 8000), 0 ); // hit like a 10kg weight at 400 in/s
			def.AddAmmoType("CombineCannon",		DMG_BULLET,					TRACER_LINE,			"sk_npc_dmg_gunship_to_plr", 	"sk_npc_dmg_gunship", NULL, 1.5 * 750 * 12, 0 ); // hit like a 1.5kg weight at 750 ft/s
			def.AddAmmoType("AirboatGun",			DMG_AIRBOAT,					TRACER_LINE,			"sk_plr_dmg_airboat",		"sk_npc_dmg_airboat",		NULL,					BULLET_IMPULSE(10, 600), 0 );
			def.AddAmmoType("StriderMinigun",		DMG_BULLET,					TRACER_LINE,			5, 5, 15, 1.0 * 750 * 12, AMMO_FORCE_DROP_IF_CARRIED ); // hit like a 1.0kg weight at 750 ft/s
			def.AddAmmoType("HelicopterGun",		DMG_BULLET,					TRACER_LINE_AND_WHIZ,		"sk_npc_dmg_helicopter_to_plr", "sk_npc_dmg_helicopter",	"sk_max_smg1",	BULLET_IMPULSE(400, 1225), AMMO_FORCE_DROP_IF_CARRIED | AMMO_INTERPRET_PLRDAMAGE_AS_DAMAGE_TO_PLAYER );
			def.AddAmmoType("AR2AltFire",			DMG_DISSOLVE,					TRACER_NONE,			0, 0, "sk_max_ar2_altfire", 0, 0 );
			//***
		}

		return &def;
	}




Let's Finish

Import skills data

Few people noticed that NPCs were not causing any damage to the player and that they could die instantly. This issue is simply caused by the fact the file skill.cfg is missing from the "\cfg" directory in the mod-dir. To fix it, get the skill.cfg file located in the Half-Lfe 2 folder.

Models Animations

You have to replace the HL2DM NPCS animations by the HL2 ones. Indeed HL2DM overrides the NPCs animations - used for the player models - so it breaks the AI. Thus, you have to use other models files for the players. You can hexedit the HL2DM player models & animations to make it tight. You will also have to put the HL2 original models in your \models folder. Finally, do not forget to modify the code related to the player models list in the hl2mp_player.cpp file.

Well, I don't want you to waste time hex-editing the model files, so I borrowed Garry's models, you can downoad the whoe package here: aifix.rar


Hope it helps! Happy modding!


Template:Otherlang:en Template:Otherlang:en:fr