home · browse · search · game entities · user directory · message board · IRC | register

July 14, 2007, 6:01 am PDT
forgot password?

Popular Resources
  • Half-Life 2 Mod FAQ
  • Valve Hammer Editor
  • Hammer 3.5 beta test
  • Half-Life Utilities
  • game data files
  • ZHLT 2.5.3 custom build
  • Half-Life SDK
  • Feedback
    If you've got any feedback, suggestions, or bugs to report regarding the Collective website, go here!

  • Feedback (302)
  • Newsletter
    Enter your email address in the above form to add yourself to the email newsletter list. Click here for more info.

    Hosted Sites
  • Valve ERC
  • Collective
  • TFMapped
  • Spirit of Half-Life
  • Selective Design
  • Pixel Reviews
  • recent articles

    NPC and Item Placement Theory
    17/03/05 11:35pm PST
    Non-Player Character (NPC) and item placement can influence both the gameflow and immersion of a level. This article aims to give some pointers on how to properly place them.
    - Hugh 'Hugh' Lloyd

    Got Props?
    13/03/05 08:32am PST
    A common problem in HL2 mapping is props not showing up in game. This article explains why and offers solutions.
    - Jeff 'Yesukai' Pritchard

    Simulating Randomness
    18/12/04 11:29pm PST
    This article focuses on how to properly simulate random events that should occur at a certain average frequency, or within a certain probability per period of time.
    - Skyler 'Zipster' York

    Adding Single-Player Weapons to Half-Life 2
    15/12/04 06:52pm PST
    Covers the process behind adding weapons to a single-player Half-Life 2 modification.
    - Skyler 'Zipster' York

    Your world in HL2
    06/12/04 12:17am PST
    This article gives tips and advice to anyone wanting to make custom photorealistic textures to be used in Half-Life 2.
    - Oksid

    Hiding in Shadow
    21/08/04 01:11pm PDT
    Describes how to create a function that has monsters disregard you if you are hiding in a certain level of "darkness," which can be set from within map properties.
    - Anders [Wolf] Jenbo (NoBody)

    XSI EXP for Half-Life 2 Tutorial - Camera Control
    23/09/04 12:43am PDT
    A SOFTIMAGE|XSI tutorial explaining all of the camera controls available to you in XSI!
    - Josh Enes

    Bump Mapping in Half-Life
    08/08/04 11:58am PDT
    Details a method of achieving real-time bump mapping in Half-Life, and provides an implementation of the algorithm.
    - Francis 'DeathWish' Woodhouse

    Real-Time "TRON 2.0" Glow For Low-Spec Hardware
    19/06/04 02:06pm PDT
    A sequel to the original "Real-Time 'TRON 2.0' Glow" article, this describes how to implement real-time glow that works on low-spec graphics cards.
    - Francis 'DeathWish' Woodhouse

    Hitboxes and Code
    05/06/04 06:25pm PDT
    How do I make only one part of a monster take damage? Learn about the relationship between model hitboxes and what you can do with them in a characters code.
    - Jonathan 'Teh_Freak' Smith

    Basing one monster class off another
    [Tue Nov 12, 2002 / 07:37pm PST] Caleb 'Ghoul' Delnay - comments (16) comments enabled

    Ok, so you want two monsters that are actually a lot alike, for example, Human Grunts and Male Assassins (from Gearbox's Opposing Force) or a scientist in a cleansuit (also from Opposing Force). Well, this is actually really simple even if you have the most basic of C++ knowlege.

    Now, programming time, let's make a cleansuit scientist. Open up your scientist.cpp file and find the Spawn function of CDeadScientist. After it we want to declare our new scientist, so:

    // Clean Suit Scientist

    class CCleanSuitScientist : public CScientist
         void Spawn(void);
         void Precache(void);
         BOOL CanHeal(void);

    This of course is our class and the functions it has. Notice that it is public CScientist. This gives our CCleanSuitScientist all the same funcions as a normal CScientist. However, we are overriding three of the CScientist functions with our own functions. We need a new Spawn function because this is where the model for the monster is set, and our cleansuit scientist has a cleansuit on, not a normal lab coat. A new Precache is needed because the cleansuits model file is precached here by the engine, and we wouldn't want to precache the wrong model, now would we? Finally, we have an overridden CanHeal function because the normal Opposing Force model doesn't have a needle to even heal you with, so having a cleansuit scientist heal you with nothing wouldn't make sense, right? So, now we need the actual bodies of these functions, which will go right below, but first don't forget the link function which adds your monster to an entity name!

    LINK_ENTITY_TO_CLASS( monster_cleansuit_scientist , CCleanSuitScientist);

    That should do, now for the three functions.

    BOOL CCleanSuitScientist::CanHeal(void)
         return FALSE;

    Ok, this is our overridden CanHeal function. It always returns FALSE no matter what, so the scientist will never be able to heal you. Now for the Spawn function.

    // Spawn

    void CCleanSuitScientist::Spawn(void)
         Precache( );

         SET_MODEL(ENT(pev), "models/cleansuit_scientist.mdl");

         pev->solid               = SOLID_SLIDEBOX;
         pev->movetype          = MOVETYPE_STEP;
         m_bloodColor          = BLOOD_COLOR_RED;
         pev->health               = gSkillData.scientistHealth;
         // position of the eyes relative to monster's origin.
         pev->view_ofs          = Vector ( 0, 0, 50 );

         // NOTE: we need a wide field of view so scientists will notice player and say hello
         m_flFieldOfView          = VIEW_FIELD_WIDE;
         m_MonsterState          = MONSTERSTATE_NONE;

    //     m_flDistTooFar          = 256.0;

         m_afCapability          = bits_CAP_HEAR | bits_CAP_TURN_HEAD | bits_CAP_OPEN_DOORS | bits_CAP_AUTO_DOORS | bits_CAP_USE;

         // White hands
         pev->skin = 0;

         if ( pev->body == -1 )
         { // -1 chooses a random head
              // pick a head, any head
              pev->body = RANDOM_LONG(0, NUM_SCIENTIST_HEADS-1);

         // Luther is black, make his hands black
         if ( pev->body == HEAD_LUTHER )
              pev->skin = 1;
         SetUse( FollowerUse );

    Notice that it is almost exactly like the normal scientists Spawn function, except we are setting the model to have a different model. Next up is the Precache function!

    // Precache - precaches all resources this monster needs

    void CCleanSuitScientist::Precache(void)

         // every new scientist must call this, otherwise
         // when a level is loaded, nobody will talk (time is reset to 0)



    Again this is almost exactly like the CScientist's Spawn function, but we are precaching our cleansuit model and not the normal scientist model.

    Oddly enough, thats it! Now you should be able to add in your monster_cleansuit_scientist entry into the .fgd and place him in a map. All should work fine assuming you have the model in your models directory!

    While this technique seems quite a waste compared too the other shorter method of creating such slightly different monsters, it works. However, I find this method perfect when making things very similar like different zombie types, or perhaps new marine types with different settings and the like. Good luck and good programming!
    article created on Tue Nov 12, 2002 / 05:51pm PST
    this item has been viewed 3589 times
    [Half-Life / coding]

    Only registered users can post comments. Have you registered yet?

    user comments

    displaying comments of normal or higher rating


    Michael Allen
    Sun Nov 24, 2002 / 01:09pm PST

      Very interesting article Caleb. I found it to be very useful in advancing my knowledge on the Half-Life SDK. :)


    Steffan Mensikov
    Wed May 28, 2003 / 12:36pm PDT

      I tried this out and the cleansuit scientists did not appear in the maps. In the console is this message:
    "Cant int monster_cleansuit_scientist"
    Being new to coding (I have only mapped until now) I have no idea where I have gone wrong. Have I made a mistake in the coding, fdg or mod set-up? A pointer in the right direction would be helpful.


    Sat Jun 21, 2003 / 06:53pm PDT

      i am a mapper and wont dare touch the code (before i know it a scientist will come running at me armed with a barney shouthing theres no place like home).......

    no i think il just keep the codes in one piece for everyones sake....

    however if you know a way to make marines and grunts buddies let me know

    for example change grunts ai's with barneys ai's or something (please dont let it be i cant stand the grunts being as retarded as barney :( )


    Sat Jun 21, 2003 / 07:47pm PDT

      Don't they somewhat do that with Sven Co-op? I know that they have friendly Marines in there... which are green as opposed to the urban camoflauged enemy Marines. (Psst... just to let everyone know... Marines are basically grunts... same thing. But in Uncle Sam's Misguided Children, grunts are considered to be ground-side Marines who are always involved in combat. All grunts are Marines, not all Marines are grunts.) Don't forget Opposing Force... those Marines are on your side... perhaps they could be brought in to Half Life? Or does that require changing a lot of code? Just throwing a thought out there.


    Lancing Fury
    Sun Jun 22, 2003 / 06:47am PDT

      well... in sven co-op, they have friendly versions of all monsters.

    and no, it would not be hard to make marines friendly in half-life at all.


    Lancing Fury
    Sun Jun 22, 2003 / 06:47am PDT

      you would just change the faction code of the grunts to be friendly to players. its just removing part of one line of code.


    Gunsmith Dragon
    Fri Jul 18, 2003 / 07:37pm PDT

      Okay. I'm new to coding, and I added the code for the cleansuit scientist as posted above. It compiled all right, but I don't know how to change the fgd. I tried copying the monster_scientist lines and modifying them, but it didn't work. Any ideas?


    ~Gunsmith Dragon


    Michiel "MuzzleFlash" Breddels
    Sat Jul 19, 2003 / 03:34am PDT

      Im gonna try this one soon, but after the coding, is it possible to add this monster_cleansuit_scientist to the current HL FDG file as an new monster entity?



    Sat Jul 19, 2003 / 04:22pm PDT

      MuzzleFlash > Yes, it's easy, you just have to add this after the monster_scientist of your MODs .fgd file (half-life.fgd for example) :
    @PointClass base(Monster, TalkMonster) size(-16 -16 0, 16 16 72) = monster_cleansuit_scientist : "Clean Suit Scientist"
    body(Choices) : "Body" : -1 =
              -1 : "Random"
              0 : "Glasses"
              1 : "Einstein"
              2 : "Luther"
              3 : "Slick"



    Michiel "MuzzleFlash" Breddels
    Sun Jul 20, 2003 / 04:28am PDT

      Cool. And the model of the monster_cleansuit_scientist itself, do i have to place it in valve/models or my own modfolder/models? Bcus we are talking about the same monster that is in OppFor? Do i gave to copy that one?



    Caleb 'Ghoul' Delnay
    Sun Jul 20, 2003 / 02:56pm PDT

      If it is for your mod, it would go in modfolder/models.


    Michiel "MuzzleFlash" Breddels
    Mon Jul 21, 2003 / 04:39am PDT

      Roger that.




    Xen Master
    Fri Jul 25, 2003 / 11:12pm PDT

      I get errors when compiling. It says:

    Error E2235: .\scientist.cpp 12213: Member function must be called or its address taken in function CCleansuitScientist::Spawn

    Can somebody help me. I just started coding last week. :(
    comment modified on Fri Jul 25, 2003 / 11:19pm PDT


    Michiel "MuzzleFlash" Breddels
    Sat Apr 10, 2004 / 03:48pm PDT

      I got a black skinned Barney, and i want him to behave just like the normal barney. How can i do that? I tried copieng the scientist code in this tutorial, but the scientist code is different then the barney code.


    As you can see, i got some more different barneys, and actually i want all of them behaving like the normal barney. But WITH their own fgd entry.
    comment modified on Sat Apr 10, 2004 / 03:50pm PDT


    Jonathan 'Teh_Freak' Smith
    Sat Apr 10, 2004 / 07:19pm PDT

      Try something like this at the end of the barney.cpp file:

    class CBlackBarney: public CBarney
    void Spawn(void);
    void Precache(void);

    LINK_ENTITY_TO_CLASS( monster_barney_black , CBlackBarney);

    Then just copy/paste the origonal barney's Spawn and Precache functions below that (but make sure you precache the proper model).

    For the FGD, same thing as the normal barney's entry, but monster_barney is now monster_barney_black.


    Michiel "MuzzleFlash" Breddels
    Sun Jan 28, 2007 / 05:03am PST

      Holy crap! Have'nt been posting here since... 2004?

    Anyway, there's a problem in your code i geuss, Ghoul.

    I've added the code, but the cleansuit scientist still heals me when my health is 50 or lower. According to you article, it should'nt. The code in my scientist.cpp file is a copy of your code in this tutorial. I don't know whats wrong.

    Do you?

    VERC © 2004. All content copyright its respective owner, all rights reserved.
    script execution time: 0.246332883835 seconds