Écrit par David Henry, le 1er septembre 2002
Attention : cet article a été écrit pour le SDK 2.2 d'Half-Life 1 ! Il se peut qu'il ne soit pas entièrement compatible avec des versions antérieures ou supérieures du Kit.
Qu'est ce qu'un item ? un item, c'est un objet que l'on peu ramasser, et parfois stocker dans son inventaire. Par exemple dans Half-life, les médikits, les batteries, la combinaison HEV et le module de grand saut sont des items. Ici nous allons voir comment coder un simple item. Ça se passe côté mp.dll...
La classe de base, c'est CItem
(dérivée de CBaseEntity
). Toute
classe d'un item en est dérivée. Lors de la définition de classe d'un item, seules deux
fonctions sont surchargées : Spawn()
et MyTouch()
, plus une
fonction Precache()
. Les items sont définis dans item.cpp, sauf pour
le médikit qui est codé dans healthkit.cpp. Voici le squelette d'une classe et de
ses fonctions membres d'un item :
///////////////////////////////////////////////////////////////////////////// // // CMonItem - classe pour mon super item. // ///////////////////////////////////////////////////////////////////////////// class CMonItem : public CItem { void Spawn () { Precache(); SET_MODEL (ENT (pev), "models/w_monitem.mdl"); CItem::Spawn (); } void Precache () { PRECACHE_MODEL ("models/w_monitem.mdl"); } BOOL MyTouch (CBasePlayer *pPlayer) { return TRUE; } };
Comme vous pouvez le voir, y'a pas grand chose. D'ailleurs, tout va se jouer ensuite dans
la fonction MyTouch()
qui est appelé lorsqu'un joueur touche l'item. Dans
Spawn()
, on se contente de précacher les ressources utilisées (ici le world
model de l'item), d'afficher le .mdl puis le travail est fini par la fonction
de base (CItem::Spawn())
).
Chaque item possède un identifiant. Vous pouvez trouver les identifiant des items déjà existant dans weapon.h :
// constant items #define ITEM_HEALTHKIT 1 #define ITEM_ANTIDOTE 2 #define ITEM_SECURITY 3 #define ITEM_BATTERY 4
Si votre item est un objet stockable en quantité (comme par exemple des clefs...), vous
pouvez utiliser la variable m_rgItems[]
en accédant à l'objet avec l'identifiant
de votre item et en l'incrémentant :
BOOL MyTouch (CBasePlayer *pPlayer) { pPlayer->m_rgItems[ITEM_MONITEM] += 1; return TRUE; }
En revanche, si votre item est un objet que l'on peu avoir qu'une fois (comme la combinaison HEV ou le module de grand saut), il faudra tester si l'objet est ou pas déjà dans l'inventaire. Ici par exemple, vous ne pouvez ramasser l'item que si vous avez la combinaison HEV :
BOOL MyTouch (CBasePlayer *pPlayer) { if (pPlayer- pev- weapons & (1 << WEAPON_SUIT)) return FALSE; pPlayer->m_rgItems[ITEM_MONITEM] += 1; return TRUE; }
Le cas de la combinaison HEV est un peu plus complexe car elle est considérée comme une arme. Mais vous pouvez faire aussi le test avec un autre simple item :
BOOL MyTouch (CBasePlayer *pPlayer) { // on ne peut prendre que 10 objets ITEM_MONITEM maximum! if (pPlayer->m_rgItems[ITEM_MONITEM] > 10) return FALSE; pPlayer->m_rgItems[ITEM_MONITEM] += 1; return TRUE; }
Enfin, pour ajouter votre item dans le fichier fgd :
@PointClass size(-16 -16 0, 16 16 36) base(Weapon, Targetx) = item_monitem : "Mon Item" []
L'entité world_items (CWorldItem
, items.cpp) permet de choisir
l'item à placer dans la map parmi toute une liste d'items. Pour rajouter votre nouvel item,
ajoutez un simple cas dans le switch
de m_iType
dans la fonction
Spawn()
:
void CWorldItem::Spawn () { CBaseEntity *pEntity = NULL; switch (m_iType) { case 46: // ITEM_MONITEM: pEntity = CBaseEntity::Create ("item_monitem", pev->origin, pev->angles); break; } // ... }
Faites attention cependant au numéro que vous lui attribuez (pour qu'il n'y ai pas de conflits avec d'autres items). Et dans le fichier fgd, allez à l'entité world_items et rajoutez votre item :
@PointClass base(Weapon, Targetx) = world_items : "World Items" [ type(choices) :"types" : 42 = [ 42: "Antidote" 43: "Security Card" 44: "Battery" 45: "Suit" 46: "Mon Item" ] ]
Cet article est mis à disposition sous un contrat Creative Commons (licence CC-BY-ND).