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

October 24, 2006, 8:50 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 (301)
  • 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

    Hiding in Shadow
    [Sat Aug 21, 2004 / 01:11pm PDT] Anders [Wolf] Jenbo (NoBody) - comments (24) comments enabled

    In this article I will explain how to make a monster disregard the player if they're within a certain level of light, and how you can define this level of light from within the map.

    Reading the Map Properties

    First we need to get the data from the map properties and store it in a variable. Open dlls\world.cpp and add the bold code just before the CWorld :: KeyValue, around line line 674.

    int g_darklevel;

    // Just to ignore the "wad" field.

    void CWorld :: KeyValue( KeyValueData *pkvd )

    Then, just before the last else, add the bold code:

    else if ( FStrEq(pkvd->szKeyName, "defaultteam") )
    if ( atoi(pkvd->szValue) )
    pev->spawnflags |= SF_WORLD_FORCETEAM;
    pkvd->fHandled = TRUE;
    else if ( FStrEq(pkvd->szKeyName, "darklevel") )
    g_darklevel = atoi(pkvd->szValue);
    pkvd->fHandled = TRUE;

    else CBaseEntity::KeyValue( pkvd );}

    Now we will need to declare the variable as a global, as we will need to read it from another part of the DLL for the next part. We could make our own .h, but it's easier to just use cbase.h as it's already included where we need the variable. Open dlls\cbase.h and add the bold code in the very beginning:

    extern int g_darklevel;

    The Actual Check

    Open dlls\player.cpp, and as the first thing in the CBasePlayer::Classify, around line 1603, add the bold code:

    // ID's player as such.

    int CBasePlayer::Classify ( void )
    if (Illumination() <= g_darklevel)
    return CLASS_NONE;

    return CLASS_PLAYER;

    This just compares the variable to the current illumination. If this checks out, it returns CLASS_NONE which monsters ignore; if the illumination is higher, it returns CLASS_PLAYER and monsters will attack. The illumination is a function that is already in the player.cpp. It simply takes the brightness of the light map under the player and adds a virtual muzzle flash light value to it (if the player fires a gun).

    The brightness of the muzzle flashes can be changed accordingly in dlls\weapons.h (Note that this doesn't change the actual muzzle flash). Also note that any values above 255 will simply add to the time of the effect.

    #define BRIGHT_GUN_FLASH 512
    #define NORMAL_GUN_FLASH 256
    #define DIM_GUN_FLASH 128

    Muzzle flash definitions for various weapons:

    mp5grenade      BRIGHT_GUN_FLASH

    shotgun NORMAL_GUN_FLASH

    hornetgun DIM_GUN_FLASH

    The Gauss and Egon should also have an effect on the illumination, correct? Note that we can add any of the 3 muzzle flash definitions to the weapons, but for this article we will be using BRIGHT_GUN_FLASH. Now for the Egon, open dlls\egon.cpp and go to line 289. Add the bold code after case FIRE_WIDE: but outside the #ifndef CLIENT_DLL, as the light check happens on the server side.

    case FIRE_WIDE:

    m_pPlayer->m_iWeaponFlash = BRIGHT_GUN_FLASH;

    #ifndef CLIENT_DLL

    Then for the Gauss, open dlls\gauss.cpp and add the muzzle flash next to the fire animation, like so.

    // player "shoot" animation
    m_pPlayer->SetAnimation( PLAYER_ATTACK1 );

    m_pPlayer->m_iWeaponFlash = BRIGHT_GUN_FLASH;


    Say, for example, we also need it to illuminate when the Gauss overcharges. Here we want the player to glow for the same amount of time that the effect lasts, so we use a fixed value for the muzzle flash. Add the bold code where that happens.

    if ( m_pPlayer->m_flStartCharge < gpGlobals->time - 10 )
    // Player charged up too long. Zap him.

    m_pPlayer->m_iWeaponFlash = 768;

    However, the illumination doesn't include dynamic lights like the flashlight, so we will have to add this ourselves. Back in dlls\player.cpp find CBasePlayer :: Illumination, which should be around line 4130. Add the bold code:

    int CBasePlayer :: Illumination( void )
    int iIllum = CBaseEntity::Illumination( );

    if (!FlashlightIsOn() == false)
    iIllum += 200;

    iIllum += m_iWeaponFlash;
    if (iIllum > 255)
    return 255;
    return iIllum;

    You could also add other conditions (such as crouching) in this way.

    Developer Tools

    Assuming you will want to debug maps that use this feature, you would probably want to add a developer command to test illumination levels around the map. To do this, we will have to add a CVAR. This is basically done the same way we added the global variable. Open dlls\game.cpp and add the bold code right after the #include's:

    #include "extdll.h"
    #include "eiface.h"
    #include "util.h"
    #include "game.h"

    cvar_t devlight = { "dev_light", "0" };

    Then move down to the GameDLLInit and add the bold code

    void GameDLLInit( void )
    // Register cvars here:

    CVAR_REGISTER (&devlight;);

    Now open dlls\game.h and right after extern void GameDLLInit( add the bold code.

    extern void GameDLLInit( void );

    extern cvar_t devlight;

    extern cvar_t displaysoundlist;

    Then open player.cpp and find PreThink, around line line 1769. Add the bold code to the beginning of the function:

    void CBasePlayer::PreThink(void)

    if (devlight.value != 0)
    ALERT ( at_console, "You are standing in %d light!\n",Illumination() );

    int buttonsChanged = (m_afButtonLast ^ pev->button); // These buttons have changed this frame

    I use PreThink because it updates every frame, so we will get the light value real-time. To activate the light tester in-game, you have to be in developer mode, which you can activate by bringing down the console and type dev_light 1.

    The FGD

    Finally, we need to edit the FGD to include this new option. Open a Half-Life FGD in Wordpad, and search for worldspawn, then add the bold code in between the other options. Make sure the proper game configuration and FGD are selected when loading Valve Hammer Editor.

    @SolidClass = worldspawn : "World entity"
    message(string) : "Map Description / Title"
    skyname(string) : "environment map (cl_skyname)"
    darklevel(integer) : "Hide shadow 0-255 (0=black)" : 15"
    sounds(integer) : "CD track to play" : 1

    Then, to set the needed light level in a map within Valve Hammer Editor, go to Map Properties and edit the value in the Hide shadow field. ("Map Properties" essentially accesses the worldspawn entity, in case you haven't noticed.)

    Lastly, I would like to thank Teh_Freak for helping me with some of the functions.
    article created on Thu Aug 19, 2004 / 09:27am PDT
    this item has been viewed 17280 times
    [Half-Life / coding]

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

    24 results, 2 pages, viewing page 1.
    prev [ 1 2 ] next

    user comments

    displaying comments of normal or higher rating


    Mon Oct 18, 2004 / 11:50am PDT

      Very nice indeed. Other factors you may want to take into consideration is if the player is walking or not, and if they are crouching.


    Anders [Wolf] Jenbo (NoBody)
    Mon Oct 18, 2004 / 02:14pm PDT

    There seams to be a similarly system that allos the AI to here you, the best way would probably be to add walk and run in to it, it should be in the in the same fashion I added the flash light in this one.
    I would probably make crouching subtract from the light value as it make you harder to see even if you are in a bright spots.


    Mon Oct 18, 2004 / 02:19pm PDT

      good tut but i would adapt it to use the cbasemonster a.i for allowing me to controll what monsters can't see you
    comment modified on Mon Oct 18, 2004 / 02:20pm PDT


    Thu Oct 21, 2004 / 02:52pm PDT

      Good article. I'll probably take advantage of this.


    Fri Oct 22, 2004 / 05:05am PDT

      hehe, add a yellow gem into the HUD and we can make a "Thief" mod.


    Fri Oct 22, 2004 / 02:07pm PDT

      In response to mathews post, what I thought was instead of changing the player class to CLASS_NONE, you could crete a class that affects different monsters to see you. for example:

    in cbase.h create a new line something like this...

    #define CLASS_PLAYER_BIOWEAPON 12 // hornets and snarks ...
    #define CLASS_ALIEN_BIOWEAPON 13 // hornets and snarks ...
    #define CLASS_SHADOWS 14 // Only certain monsters can see you
    #define CLASS_BARNACLE 99

    Now open up monsters.cpp and find the monster relationship table, I think it's called IRelationship, inside you'll find all the classes and how they react to one another...

    Underneath you will need to add another line something like this...

         /*ShADOWS*/ { R_NO,     R_NO,     R_NO,     R_NO... etc

    Now you need to create another coloumn in the table to show how other monsters react to you. Because I believe that some of the alien creatures have something akin to night vision, mine goes something lke this..

    Then, where you're told to put CLASS_NONE at the top of the tutorial, just put CLASS_SHADOWS

    Hope that helps!:)
    comment modified on Fri Oct 22, 2004 / 02:09pm PDT


    Sun Oct 24, 2004 / 06:47am PDT

      There's one thing to nitice: neither GETENTITYILLUM(), nor pev->light_level doesn't work properly (especially with dynamic light). :(


    Sun Oct 24, 2004 / 08:24pm PDT

      This isn't a very good method to do something like this. A player could be standing in a shadow, with a bright background, and a monster wouldn't be able to see the player. It's prone to errors.

    The better idea would be to place specific zones players can hide themselves in. The mapper can have more control then, and ensure specific areas are reasonable for hiding in.


    Captain P
    Mon Oct 25, 2004 / 01:25am PDT

      Or do a ray trace from the monster trough the player (player's origin? player's head? multiple positions?) onto the surface behind the player, then determine the brightness of that surface and take that into the visibility determination of the player... (mhh, what about ray tracing to a sky surface...)
    Or at least that's what I think about it...

    Too bad I have nearly no time to test this tutorial... :|


    Hugh 'Hugh' Lloyd
    Mon Oct 25, 2004 / 11:58am PDT

      That would be super-tedious for the mapper to have to set it up, Sniper. And what sort of map has a shadowy ground with a bright background? A really crappy one, that's right.


    Mon Oct 25, 2004 / 03:17pm PDT

      A crappy one? I beg to differ.


    João "Skoiler" Valente
    Tue Oct 26, 2004 / 11:34am PDT

      I'll have to agree with Hugh. Bright background with shadowy ground is kinda... errr... Give examples, Sniper :D


    Daniel "Raminator" Junek
    Tue Oct 26, 2004 / 03:10pm PDT

      What if you're in the shadow of a bridge, building, etc. outside? Then you'd be in shadow but the background wouldn't.


    Robert "Campaignjunkie" Yang
    Tue Oct 26, 2004 / 03:33pm PDT

      You can probably hack something like the situation Sniper describes (it's certainly possible), but I agree with Hugh about it being very tedious. I guess it's just another limitation for mappers; make sure shadow is near a darkened wall for "realism" purposes, even though I doubt most players will care about it. Heck, some people can't even tell the difference between Half-Life 1 and Doom 3. :)

    For a sample of HL using this kind of dynamic, try Puppy Years:
    comment modified on Tue Oct 26, 2004 / 03:35pm PDT


    Loc 'Loc' Visse
    Tue Nov 02, 2004 / 10:24am PST

      Well, actually, having a monster (say a zombie) in a dark corridor and a 'bright' (not overbright of course, imagine a dim red light) background behind gives a nice scary effect to it. You can see the monster's dark shape slowly heading toward you.


    Jethro 'deathz0rz' Beekman
    Fri Nov 05, 2004 / 06:53am PST

      if (!FlashlightIsOn() == false)

    ... have I said enough?


    Jonathan Elliott
    Sun Nov 07, 2004 / 01:20am PST

      this could be good if you are following a character and the guards cannot see you.


    Guillermo "t3chn0r" Gisinger
    Wed Nov 24, 2004 / 04:08pm PST

      Very nice article Wolf but why complicate the things with

    if (!FlashlightIsOn() == false) %)

    When you can easily do it like

    if (FlashlightIsOn()) :)

    It's also easier to read...

    Good article though... very interesting!


    Anders [Wolf] Jenbo (NoBody)
    Mon Dec 06, 2004 / 01:21pm PST

      Now that would have been to easy wouldn't it :P


    Sun Dec 12, 2004 / 05:42am PST

      Snipers situation is perfectly possible

    player walking against Neon lights (they give of little light but just glow)

    I was at 1 point trying to make a stealth mod, i might try again. This is useful thanks
    comment modified on Sun Dec 12, 2004 / 05:44am PST

    24 results, 2 pages, viewing page 1.
    prev [ 1 2 ] next

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