Fr/Fixing AI in multiplayer: Difference between revisions

From Valve Developer Community
< Fr
Jump to navigation Jump to search
(Rewrite Template:Lang to Template:LanguageBar. This action was performed by a bot.)
 
(11 intermediate revisions by 9 users not shown)
Line 1: Line 1:
[[Category:Programming]]
{{LanguageBar|Fixing AI in multiplayer|title=Activer et Corriger l'IA en Coop}}
{{ACategory|Networking}}
=Introduction=
=Introduction=
Salut à tous!
Cet article est une mise-à-jour de l'article '''Activer IA en Coop'''.
Cet article est une mise-à-jour de l'article '''Activer IA en Coop'''.
Bien que l'ancienne version expiquait comment activer l'IA dans une partie multijoueurs, il s'avérait que les NPCs de type humanoïdes tels que les ''Combine Soldiers'' ne pouvaient pas se déplacer, ni tirer sur le joueur, et c'est frustrant!
Bien que l'ancienne version expiquait comment activer l'IA dans une partie multijoueurs, il s'avérait que les NPCs de type humanoïdes tels que les ''Combine Soldiers'' ne pouvaient pas se déplacer, ni tirer sur le joueur, et c'est frustrant!
Line 8: Line 7:


Avant que l'on aille plus loin, j'aimerais juste remercier au passage Garry Newman BunkMug, FoxFire, pour leurs tuyaux ainsi que d'autres personnes sur divers forums.
Avant que l'on aille plus loin, j'aimerais juste remercier au passage Garry Newman BunkMug, FoxFire, pour leurs tuyaux ainsi que d'autres personnes sur divers forums.


=Tabes des Relations=
=Tabes des Relations=
Line 14: Line 12:
D'abord, on doit définir cette table en définissant les différentes classes des personnages présents dans le jeu.
D'abord, on doit définir cette table en définissant les différentes classes des personnages présents dans le jeu.
Ouvrez le fichier '''BaseEntity.h''', puis dans la définition de '''enum Class_T''', après le bloc '''#elif defined( CSTRIKE_DLL )''' ajoutez ceci:
Ouvrez le fichier '''BaseEntity.h''', puis dans la définition de '''enum Class_T''', après le bloc '''#elif defined( CSTRIKE_DLL )''' ajoutez ceci:
<pre>
<pre>
//***THOMAS*** INITIALISE LA TABLE DES RELATIONS DES NPC ( =PNJ ) POUR HL2DM
//***THOMAS*** INITIALISE LA TABLE DES RELATIONS DES NPC ( =PNJ ) POUR HL2DM
Line 52: Line 49:


==Utilisation de la Table==
==Utilisation de la Table==
Super! Maintenant il nous faut dire aux ''Game Rules'' d'utiliser cette Table de Relations dans le jeu lorque l'on commence une partie de HL2DM.
Super! Maintenant il nous faut dire aux ''Game Rules'' d'utiliser cette Table de Relations dans le jeu lorque l'on commence une partie de HL2DM.
Ouvrez le fichier '''h2mp_gamerules.h'''. En dessous de l'onglet '''public:''', ajoutez ceci:
Ouvrez le fichier '''h2mp_gamerules.h'''. En dessous de l'onglet '''public:''', ajoutez ceci:
Line 63: Line 59:
//***
//***
</pre>
</pre>
A présent, ouvrez le fichier '''h2mp_gamerules.cpp'''. Ensuite tout en bas du fichier ''.cpp'' ajoutez tout ce bout de code:
A présent, ouvrez le fichier '''h2mp_gamerules.cpp'''. Ensuite tout en bas du fichier ''.cpp'' ajoutez tout ce bout de code:
<pre>
<pre>
Line 82: Line 75:
//***
//***
</pre>
</pre>
Terminons en ajoutant cette petite instruction dans la fonction CHL2MPRules::CHL2MPRules():
Terminons en ajoutant cette petite instruction dans la fonction CHL2MPRules::CHL2MPRules():
<pre>
<pre>
//***THOMAS*** INITIALISE LA TABLE DES RELATIONS DES NPC ( =PNJ ) POUR HL2DM
//***THOMAS*** INITIALISE LA TABLE DES RELATIONS DES NPC ( =PNJ ) POUR HL2DM
Line 93: Line 81:
//***
//***
</pre>
</pre>


=Faire fonctionner les NPCs humanoides=
=Faire fonctionner les NPCs humanoides=
===Animations des Armes==
==Animations des Armes==
 
Pour chaque arme, prendre le code SP de l'arme, et copier la liste des animations contenues dans la structure ''acttable_t''.
Pour chaque arme, prendre le code SP de l'arme, et copier la liste des animations contenues dans la structure ''acttable_t''.
Procédez comme ci-dessous:
Procédez comme ci-dessous:
Line 120: Line 106:
}
}
</pre>
</pre>


==Autres modifications sur les armes==
==Autres modifications sur les armes==
Il faut à présent insérer le code qui permet à l'IA de controller son arme, en l'occurrence de tirer avec, de la recharger etc. Pour ce faire, il faut déclarer ces deux fonctions, côté serveur seulement:
Il faut à présent insérer le code qui permet à l'IA de controller son arme, en l'occurrence de tirer avec, de la recharger etc. Pour ce faire, il faut déclarer ces deux fonctions, côté serveur seulement:
<pre>
<pre>
#ifndef CLIENT_DLL
#ifndef CLIENT_DLL
Line 135: Line 118:
</pre>
</pre>


'''NOTE:''' Vous trouverez le corps de la fonction ''Operator_HandleAnimEvent()''  dans votre copie du SDK. N'oubliez donc pas de l'insérer sinon vous risquez de génererer des erreurs à la compilation!
{{note|Vous trouverez le corps de la fonction ''Operator_HandleAnimEvent()''  dans votre copie du SDK. N'oubliez donc pas de l'insérer sinon vous risquez de génererer des erreurs à la compilation!}}
 


==Suggestions de Garry Newman==
==Suggestions de Garry Newman==
Garry Newman suggérait sur des forums de modifier la fonction ''SetActivity()''.
Garry Newman suggérait sur des forums de modifier la fonction ''SetActivity()''.
Ainsi, dans le fichier '''basecombatweapon_shared.cpp''', recherchez la fonction ''SetActivity()'', et juste après e commentaire d'Adrien:
Ainsi, dans le fichier '''basecombatweapon_shared.cpp''', recherchez la fonction ''SetActivity()'', et juste après e commentaire d'Adrien:
<pre>
<pre>
//Adrian: Oh man...
//Adrian: Oh man...
</pre>
</pre>
remplacez
remplacez
<pre>
<pre>
#if !defined( CLIENT_DLL ) && defined( HL2MP )
#if !defined( CLIENT_DLL ) && defined( HL2MP )
Line 154: Line 132:
#endif
#endif
</pre>
</pre>
par
par
<pre>
<pre>
if ( GetOwner()->IsPlayer() )
if ( GetOwner()->IsPlayer() )
SetModel( GetWorldModel() );
SetModel( GetWorldModel() );
</pre>
</pre>
Procédez de même après l'autre commentaire, vous remplacerez donc:
Procédez de même après l'autre commentaire, vous remplacerez donc:
<pre>
<pre>
//Adrian: Oh man again...
//Adrian: Oh man again...
Line 172: Line 144:
#endif
#endif
</pre>
</pre>
par
par
<pre>
<pre>
//Adrian: Oh man again...
//Adrian: Oh man again...
Line 180: Line 150:
SetModel( GetViewModel() );
SetModel( GetViewModel() );
</pre>
</pre>
Bon, je ne sais pas si ça change queque chose ou pas, mais Garry insistait sur ce code, alors je suggère qu'en en tienne compte. Si quequ'un à le courage de tester pour voir s'il y a une différence ou pas avec ce code, qu'il m'en fasse part, merci.
Bon, je ne sais pas si ça change queque chose ou pas, mais Garry insistait sur ce code, alors je suggère qu'en en tienne compte. Si quequ'un à le courage de tester pour voir s'il y a une différence ou pas avec ce code, qu'il m'en fasse part, merci.


==Ammotypes==
==Ammotypes==
Après avoir activé mes NPCs humanoides, ces derniers me tuaient en une seule balle. Si vous avec le même problème, je vous suggère de trouver la fonction ''CAmmoDef *GetAmmoDef()'' dans le fichier '''hl2mp_gamerules.cpp''', et de la remplacer entièrement par ce qui suit.
Après avoir activé mes NPCs humanoides, ces derniers me tuaient en une seule balle. Si vous avec le même problème, je vous suggère de trouver la fonction ''CAmmoDef *GetAmmoDef()'' dans le fichier '''hl2mp_gamerules.cpp''', et de la remplacer entièrement par ce qui suit.
<pre>
<pre>
CAmmoDef *GetAmmoDef()
CAmmoDef *GetAmmoDef()
Line 225: Line 191:
}
}
</pre>
</pre>


=Pour terminer=
=Pour terminer=
Line 236: Line 197:
pour corriger l'erreur, il vous faut copier/coller le fichier skill.cfg du jeu Half-Life 2 dans le répertoire
pour corriger l'erreur, il vous faut copier/coller le fichier skill.cfg du jeu Half-Life 2 dans le répertoire
''\cfg'' de votre mod.
''\cfg'' de votre mod.


==Animations des Models==
==Animations des Models==
Line 247: Line 207:
Pour éviter de recompiler les models, il est préférable de les éditer avec un éditeur hexadécimal ( models de joueurs & noms des animations ). Pour vous faire gagner du temps, je vous suggère d'utiliser des models déjà hex-édités, par exemples ceux du Garry's mod.
Pour éviter de recompiler les models, il est préférable de les éditer avec un éditeur hexadécimal ( models de joueurs & noms des animations ). Pour vous faire gagner du temps, je vous suggère d'utiliser des models déjà hex-édités, par exemples ceux du Garry's mod.


Je vous ai préparé un petit package qui contient ce dont vous avez besoin pour faire fonctionner les ''Combine Soldiers'' et les ''Citoyens''. En fait j'ai emprunté les models de Garry. Vous pouvez avec le ien vers le tléchargement à[http://dolphineye.ifrance.com/aifix.html cette page].
Je vous ai préparé un petit package qui contient ce dont vous avez besoin pour faire fonctionner les ''Combine Soldiers'' et les ''Citoyens''. En fait j'ai emprunté les models de Garry. Vous pouvez avec le ien vers le tléchargement à [http://dolphineye.ifrance.com/aifix.html cette page].
Au fait, n'oubliez pas de prendre en compte ce changement dans le code, au niveau de la liste des models de joueurs dans le fichier '''hl2mp_player.cpp'''.
Au fait, n'oubliez pas de prendre en compte ce changement dans le code, au niveau de la liste des models de joueurs dans le fichier '''hl2mp_player.cpp'''.
J'espère que ça vous aidera. @+
{{otherlang:en}} {{otherlang:fr:en|Activating and Fixing AI In Coop Games}}

Latest revision as of 17:53, 18 July 2025

English (en)Français (fr)Translate (Translate)

Introduction

Cet article est une mise-à-jour de l'article Activer IA en Coop. Bien que l'ancienne version expiquait comment activer l'IA dans une partie multijoueurs, il s'avérait que les NPCs de type humanoïdes tels que les Combine Soldiers ne pouvaient pas se déplacer, ni tirer sur le joueur, et c'est frustrant! Eh bien voilà, c'est une histoire an cienne à présent, je vous propose que l'on étudie tout celà ensembe...

Avant que l'on aille plus loin, j'aimerais juste remercier au passage Garry Newman BunkMug, FoxFire, pour leurs tuyaux ainsi que d'autres personnes sur divers forums.

Tabes des Relations

Création de la Table

D'abord, on doit définir cette table en définissant les différentes classes des personnages présents dans le jeu. Ouvrez le fichier BaseEntity.h, puis dans la définition de enum Class_T, après le bloc #elif defined( CSTRIKE_DLL ) ajoutez ceci:

//***THOMAS*** INITIALISE LA TABLE DES RELATIONS DES NPC ( =PNJ ) POUR 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
};
//***

Utilisation de la Table

Super! Maintenant il nous faut dire aux Game Rules d'utiliser cette Table de Relations dans le jeu lorque l'on commence une partie de HL2DM. Ouvrez le fichier h2mp_gamerules.h. En dessous de l'onglet public:, ajoutez ceci:

//***THOMAS*** INITIALISE LA TABLE DES RELATIONS DES NPC ( =PNJ ) POUR HL2DM
#ifndef CLIENT_DLL 
void InitDefaultAIRelationships( void );
#endif
//***

A présent, ouvrez le fichier h2mp_gamerules.cpp. Ensuite tout en bas du fichier .cpp ajoutez tout ce bout de code:

//------------------------------------------------------------------------------
// Purpose : Initialize all default class relationships
// Input   :
// Output  :
//------------------------------------------------------------------------------
//***THOMAS*** INITIALISE LA TABLE DES RELATIONS DES NPC ( =PNJ ) POUR HL2DM
#ifndef CLIENT_DLL 
void CHL2MPRules::InitDefaultAIRelationships( void )
{
	//Copiez le contenu of de hl2_gamerules InitDefaultAIRelationships ici
}
#endif
//***

Terminons en ajoutant cette petite instruction dans la fonction CHL2MPRules::CHL2MPRules():

//***THOMAS*** INITIALISE LA TABLE DES RELATIONS DES NPC ( =PNJ ) POUR HL2DM
InitDefaultAIRelationships();
//***

Faire fonctionner les NPCs humanoides

Animations des Armes

Pour chaque arme, prendre le code SP de l'arme, et copier la liste des animations contenues dans la structure acttable_t. Procédez comme ci-dessous:

acttable_t	CWeaponSMG1::m_acttable[] = 
		{
			//DEPART ANIMATIONS HL2DM
			{ ACT_HL2MP_IDLE,		ACT_HL2MP_IDLE_SMG1,		false },
			( ... )
			{ ACT_RANGE_ATTACK1,		ACT_RANGE_ATTACK_SMG1,		false },
			//FIN ANIMATIONS HL2DM

			//DEPART ANIMATIONS HL2
			{ 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 },
			//FIN ANIMATIONS HL2

		}

Autres modifications sur les armes

Il faut à présent insérer le code qui permet à l'IA de controller son arme, en l'occurrence de tirer avec, de la recharger etc. Pour ce faire, il faut déclarer ces deux fonctions, côté serveur seulement:

#ifndef CLIENT_DLL
		//PERMET AUX NPC D'UTILISER CETTE ARME
		int CapabilitiesGet( void ) { return bits_CAP_WEAPON_RANGE_ATTACK1; }
		//GESTION DES ACTIONS DE L'IA
		void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator );
#endif
Note.pngNote:Vous trouverez le corps de la fonction Operator_HandleAnimEvent() dans votre copie du SDK. N'oubliez donc pas de l'insérer sinon vous risquez de génererer des erreurs à la compilation!

Suggestions de Garry Newman

Garry Newman suggérait sur des forums de modifier la fonction SetActivity(). Ainsi, dans le fichier basecombatweapon_shared.cpp, recherchez la fonction SetActivity(), et juste après e commentaire d'Adrien:

//Adrian: Oh man...

remplacez

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

par

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

Procédez de même après l'autre commentaire, vous remplacerez donc:

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

par

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

Bon, je ne sais pas si ça change queque chose ou pas, mais Garry insistait sur ce code, alors je suggère qu'en en tienne compte. Si quequ'un à le courage de tester pour voir s'il y a une différence ou pas avec ce code, qu'il m'en fasse part, merci.

Ammotypes

Après avoir activé mes NPCs humanoides, ces derniers me tuaient en une seule balle. Si vous avec le même problème, je vous suggère de trouver la fonction CAmmoDef *GetAmmoDef() dans le fichier hl2mp_gamerules.cpp, et de la remplacer entièrement par ce qui suit.

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;
	}

Pour terminer

Le fichier skill.cfg

On m'a fait remarquer que les NPC ne causent pas de dommages au joueur, et en plus ils meurent très facilement. Ceci est simplement liée à l'absence du fichier skill.cfg dans le répertoire \cfg du mod. pour corriger l'erreur, il vous faut copier/coller le fichier skill.cfg du jeu Half-Life 2 dans le répertoire \cfg de votre mod.

Animations des Models

Pour en finir avec ces NPCs, il vous faut remplacer les animations des NPCs par celles d'origine. En clair, il faut remplacer les animations de HL2DM par celles de HL2, ce qui permettra à l'IA de fonctionner correctement car ee pourra utiliser ses propres animations, et non pas celles de H2DM qui sont différentes!

Il faut évidement utiliser d'autres animations pour les joueurs afin de ne pas corrompre leurs propres animations ( celles utiisées par HL2DM ).

Pour éviter de recompiler les models, il est préférable de les éditer avec un éditeur hexadécimal ( models de joueurs & noms des animations ). Pour vous faire gagner du temps, je vous suggère d'utiliser des models déjà hex-édités, par exemples ceux du Garry's mod.

Je vous ai préparé un petit package qui contient ce dont vous avez besoin pour faire fonctionner les Combine Soldiers et les Citoyens. En fait j'ai emprunté les models de Garry. Vous pouvez avec le ien vers le tléchargement à cette page.

Au fait, n'oubliez pas de prendre en compte ce changement dans le code, au niveau de la liste des models de joueurs dans le fichier hl2mp_player.cpp.