Half-Life² Deathmatch Coopératif ! Vous connaissez ?
Vous avez peut-être déjà croisé des maps nommées js_coop_quelqueChose ou coop_quelqueChose. La particule js vient des initiales du mappeur qui a créé la première map coopérative : Joe Scoma. Ces maps coopératives se jouent en Team-DM, mais avec une seule team (Rebel ou Combine). Les joueurs doivent terminer ensemble la map, qui peut être soit un puzzle soit une aventure. Dans le cas du puzzle, les joueurs doivent ruser pour réaliser des épreuves. Il n'y pas généralement pas de NPC. En revanche, dans les aventures, les joueurs affrontent des NPC, et c'est de ce mode de jeu que je vais vous parler...
Si vous voulez vous lancer dans le mapping HL² Coopératif, vous pouvez vous tourner vers le mod Synergy , disponible sur Steam . C'est plus abouti que HL²DM.
Dans les maps coopératives, il n'y a généralement qu'une seule équipe.
Une seule équipe signifie donc qu'une seule des deux équipes est autorisée et l'autre bannie. Malheureusement, HL²DM ne permet pas de ne jouer qu'avec une seule équipe. Il va donc falloir se débrouiller, via un jeu d'entités pour empêcher une des deux teams de respawmer, et de faire changer les joueurs d'équipe s'ils se trouvent dans la mauvaise.
Changer un joueur d'équipe se fait par le biais d'une commande. Cette commande, qui se nomme cl_playermodel, doit être envoyée à une entité point_clientcommand. Si on veut qu'un Combine devienne un Rebel, il faut que le Combine passe dans un trigger_multiple. Dès qu'il le touche, le trigger envoie la commande au point_clientcommand (nommé clientCommand) pour dire de changer le model du joueur. Donc ici, on va demander de changer pour un model de rebel.
Pour séparer les deux équipes, il suffit d'utiliser les entités info_player_rebel et info_player_combine. Les rebels sont autorisés, donc ils peuvent apparaitre dans la salle de respawn. Quand aux combines, ils ne peuvent pas se joindre aux rebels. Donc on va placer les info_player_combine dans une salle, qui contiendra le fameux trigger_multiple pour changer le joueur d'équipe. Il y aura aussi un trigger_physics_trap, pour tuer les joueurs.
Voici le schéma de ma salle de respawn :
La grande pièce est réservée aux rebels et la plus petite aux combines. J'ai donc placé les points de respawn des combines les pieds dans le trigger_physics_trap, et le bassin dans le trigger_multiple qui se chargera d'appeler le point_clientcommand, comme ceci :
Il n'y a rien de spécial à modifier pour le trigger_physics_trap. Pour le trigger_multiple, il suffit juste de lui définir l'output pour envoyer la commande que clientCommand.
Output named |
Targets entities |
Via this input |
Parameter |
Delay |
---|---|---|---|---|
OnStartTouch |
clientCommand |
Command |
cl_playermodel models/humans/group03/female_01.mdl |
0.00 |
OnTrigger |
switchCombineText |
Display |
<none> |
0.00 |
HL²DM n'est pas prévu pour utiliser des NPC, ce qui pose pas mal de différences avec les NPC dans HL², solo.
Certains NPC ne fonctionnent pas sous HL²DM. Généralement, quand vous en mettez un et qu'il ne fonctionne pas (après lui avoir défini une relation, (voir plus bas)), c'est qu'il n'est pas géré. La plupart des NPC courants sont évidemment générés, à l'exception des zombies.
Si vous mettez des zombies et que vous testez votre map, le jeu va planter. Les zombies ne fonctionnent que si la map est jouée sur un serveur tournant sous Linux. C'est con mais c'est comme ça. Si vous décidez de faire une map avec des zombies, il vous faudra obligatoirement un serveur Linux (que vous faites vous-même, ou bien un serveur dédié Linux). Si vous utilisez le Dedicated Serveur proposé via Steam, c'est un serveur Windows, pour comme tester sa ma en local directement avec HL²DM. C'est la raison pour laquelle il y a si peu de maps coop avec des zombies, c'est tout simplement casse pied pour tester.
Sous HL²DM, tous les NPC sont neutres. Comprenez, ceux qui sont normalement méchants n'attaquent pas le joueur. Il faut donc, pour chaque type de NPC, utiliser une entité ai_relationship pour définir le comportement du NPC vis-à-vis du joueur.
Prenons l'exemple du headcrab. L'entité qui permet d'insérer un headcrab est npc_headcrab. Créez une entité point ai_relationship et définissez ses propriétés comme ceci :
Name : ai_headcrab
Subjects : npc_headcrab
Targets : !player
Disposition : Hate
Start Active : No
Reciprocal : Yes
Je définis donc que les npc_headcab ne doivent pas aimer le joueur (!player) et que c'est réciproque. La relation n'est pas active par défaut. Il est conseillé de l'appliquer au chargement de la map. Pour cela, rien de plus simple, un logic_auto :
Output named |
Targets entities |
Via this input |
Parameter |
Delay |
---|---|---|---|---|
OnMapSpawn |
ai_headcrab |
ApplyRelationship |
<none> |
0.00 |
A vous de créer les autres ai_relationship, pour les autres NPC .
Il est grandement conseillé de toujours utiliser un npc_template_maker pour faire apparaitre les NPC. Un npc_template_maker est une entité qui fait apparaitre un NPC et qui a surtout la capacité d'en faire apparaitre plusieurs à la suite ou en même temps.
Faisons un exemple avec un headcrab. Créez une entité npc_headcrab, et donnez-lui comme nom template_headcrab. Ce ncp_headcrab servira de base. C'est lui que les npc_template_maker feront apparaitre.
L'entité npc_headcrab ne demande pas de configuration spécifique, hormis au niveau des flags. Comme on va utiliser l'entité par le biais d'un npc_template_maker, il va falloir l'indiquer. Pour cela, cochez le flag Template NPC.
Le npc_template_maker est assez simple à utiliser aussi. Il suffit de lui indiquer le NPC à faire apparaitre, combien de fois, et combien il peut y en avoir en vie en même temps :
Num. of NPCs : le nombre de NPC total qui seront spawnés
Frequency : la fréquence d'apparition, en secondes
Max Live NPCs : le nombre de NPC en vie en même temps. Si vous laissez 1, le npc_template_maker attendra que celui qui vit soit tué avant de faire apparaitre le second
Name of template NPC : le nom du NPC. Dans l'exemple, c'est template_headcrab
Le npc_template_maker doit être désactivé par défaut (Start active : No). Vous devez donc lui donner un nom pour l'appeler et ainsi l'activer. L'activation se fait via l'input Enable. Ca permet aussi de ne faire apparaitre que les NPC que les joueurs vont voir. Inutile donc de faire apparaitre au chargement de la map l'antlion guard que les joueurs ne verront qu'à la fin du niveau.
Output named |
Targets entities |
Via this input |
Parameter |
Delay |
---|---|---|---|---|
OnQuelqueChose |
maker_headcracb_1 |
Enable |
<none> |
0.00 |
L'entité possède aussi un flags Infinite children. Il permet de faire apparaitre un NPC une infinité de fois (jusqu'à ce que le npc_template_maker soit désactivé, avec l'input Disable). Ce flag ne marche pas bien avec les npc_manhack. Et de manière générale, on ne sait pas faire apparaitre plus d'une quinzaine de manhacks par npc_template_maker.
Eh oui, le NPC que fait apparaitre ne npc_template_maker apparait à sa place donc il ne doit pas toucher le seul pour éviter que le NPC ne se retrouve coincé.
Voici par exemple un "champ" de respawn pour headcrabs en folie (dans ma map js_copp_thunder) :
Comme je l'ai déjà dit, les NPC dans HL²DM c'est pas toujours ça. Et pour cause, tirez une fois sur un monstre, hop, il est mort. En fait, il va falloir définir "à la main" la vie de chaque type de NPC, et les dommages qu'il provoque avec ses attaques.
Pour définir ces variables (ce sont des variables dédiées, pouvant être tapées dans la console en fait), on va se servir d'une entité point_servercommand. Placez donc cette entité point, et donnez-lui comme nom serveur.
Lors du chargement de la map, il va falloir définir ces variables. Pour cela, il suffit de faire un output vers l'entité point_servercommand qui appliquera la variable. Je vous conseille de créer un logic_relay qui ne contiendra que les outputs vers le point_servercommand. Ce logic_relay sera appelé au chargement de la map, avec le logic_auto que nous avons créé pour établir les relations NCP - Joueurs.
Les outputs du logic_relay sont de ce type :
Output named |
Targets entities |
Via this input |
Parameter |
Delay |
---|---|---|---|---|
OnTrigger |
serveur |
Command |
sk_headcrab_health 50 |
0.00 |
OnTrigger |
serveur |
Command |
sk_headcrab_fast_health 50 |
0.00 |
OnTrigger |
serveur |
Command |
sk_headcrab_poison_health 50 |
0.00 |
Ces variables sk sont différentes pour chaque type de NPC. Vous pouvez consulter le wiki de Valve. Pour chaque entité , ces variables sont mentionnées .
Voici une liste de variables que j'utilise :
sk_headcrabs_health 100
sk_headcrab_melee_dmg 30
sk_headcrab_fast_health 200
sk_headcrab_poison_health 150
sk_zombie_poison_health 1000
sk_zombie_poison_dmg_spit 50
sk_zombie_health 200
sk_zombie_dmg_one_slash 50
sk_zombie_dmg_both_slash 80
sk_vortigaunt_dmg_claw 40
sk_vortigaunt_dmg_rake 50
sk_vortigaunt_dmg_zap 50
sk_vortigaunt_health 200
sk_manhack_health 100
sk_manhack_melee_dmg 25
sk_scaner_health 100
sk_antlionguard_health 5000
sk_antlionguard_dmg_shove 500
sk_antlionguard_dmg_charge 500
sk_antlion_health 1000
sk_zombie_fast_health 300
sk_gunship_health_increments 100
sk_antlion_jump_damage 500
sk_antlion_swipe_damage 500
Faites simple !!! Evitez les séquences de NPC avec par exemple des antlions qui respawnent quand le joueur marche sur le sable (ça ne marche pas), des antlions qui volent d'un point à un autre (avec ça, crash du serveur Linux garanti (bizarrement, ça marche sous Windows, le contraire des zombies quoi ))...
Contentez-vous d'utiliser un path_corner pour indiquer la destination des NPC, ne vous compliquez pas la vie .
Dans les maps coop, les armes sont toujours posées par terre. C'est idiot, il suffirait d'utiliser un game_player_equip. Et bien non ! Le game_player_equip, au-delà de 7 - 8 joueurs provoque des problèmes de connexion et d'apparition des joueurs. Ce n'est pas systématique mais ça peut arriver. Son utilisation est donc déconseillée.
Si vous faites une map coop avec des NPC (donc pas une map de type puzzle), ne donnez jamais le Gravity Gun. Le fait de tirer certains objets à la tronche des NPC (comme les antlions) peut provoquer un crash du serveur. A éviter donc.
Comme le Gravity Gun est donné par défaut, il faut donc l'enlever avec un trigger_weapon_strip.
L'entité point game_end permet de mettre fin à la map en cour. La map suivant est alors chargée. C'est le seul moyen pour changer de map quand le niveau est terminé.
Donnez un nom à votre game_end, et appelez-le au moment opportun avec l'input EndGame.
Évitez de faire trop de passages exigus dans lesquels les joueurs pourraient se bloquer. Par bloquer j'entends deux joueurs qui tentent de passer une porte en même temps... Pour éviter ça, je conseille de mettre un petit trigger_push pour les pousser et éventuellement pousser un joueur qui s'amuserait à bloquer le passage (il n'y a rien de plus embêtant que ça), en particulier dans les portes et les conduits de ventilation.
Entrer dans un téléporteur à plusieurs ne pose pas de problème. Par contre, ça peut coincer à la sortie ! Là aussi, mettez un trigger_push qui englobe les sorties de téléporteurs pour poussez les joueurs et les empêcher des se bloquer les uns dans les autres.
Une autre technique est de désactiver le téléporteur pendant une seconde à chaque fois qu'un joueur le touche. Ça peut être un bon moyen si le trigger_push ne règle pas bien le problème.