Forum posts

MESS 1.1 is now available! :)

The big changes in this version are a new 'rewrite rule' system for creating custom template-based entities, and support for J.A.C.K. map files (for template maps). The rewrite rule system makes it possible to create your own .fgd files, with custom entities like monster_warp or rh_rat, along with instructions for MESS to 'rewrite' these entities to macro-inserting entities that use a monster_warp.rmf or rh_rat.jmf template map.

Download links:
  • MESS 1.1 - The compile tool itself.
  • example maps - Updated example maps. Be sure to check out the new rathunt example, and its use of the custom rh_rat and rh_message_system entities!
Documentation:
  • Readme - An introduction to MESS, and instructions on how to get started.
  • Entity guide - Like TWHL's entity guide, but for MESS' macro entities.
  • Rewrite rules - For creating custom entities, and telling MESS to rewrite them to template-inserting entities.
  • Scripting system - Documentation for MScript, the scripting language used by MESS. See the functions section for a list of functions, many of which are new in 1.1.
Full list of changes:
  • Added a 'rewrite rule' mechanism, for creating template-based entities.
  • Added support for J.A.C.K. template map files (.jmf).
  • Added several string, math, trig, color, flags and directory-related MScript functions.
  • Added a not operator to MScript (alternative for !).
  • MScript now converts none function arguments to the default value for the parameter's type, for non-optional parameters.
  • Added a 'REPL' mode, for interactive testing of MScript expressions.
  • The special spawnflag<N> attributes now start at 0, not 1.
  • The template_name attribute is now a target_destination, so J.A.C.K. can show links between macro entities and the templates they're using.
  • Added MScript documentation.
Bugfixes:
  • Fixed that .rmf files without cameras failed to open.
Posted 3 years ago2020-12-01 13:36:44 UTC
in Post your screenshots! WIP thread Post #344988
Andy_Shou: that's looking very nice!

Kachito: that's a nice way to avoid the standard low-res GoldSource look. Very stylish!
Posted 3 years ago2020-12-01 13:05:27 UTC
in Mapping with Wall Worm? Post #344987
I haven't tried it, but it certainly sounds very interesting, especially for natural environments. It's a modern tool, useful for a lot more than just level-design, and it's also extensible.

On the other hand, 3ds Max isn't exactly cheap... If something like this was available for Blender then I would certainly give it a try, but 3ds Max just isn't worth it for me.
Posted 3 years ago2020-12-01 11:50:06 UTC
in [Help] Half-Life Flipsigns Post #344986
You're the one that decided to make a translation mod, so that's all up to you, right? If I were you I'd just leave it as it is - nobody could read it before anyway.

As for the military, Black Mesa was built around an old ICBM silo complex, and some nearby facilities were apparently still in use by the military. They were also involved in several weapon research programs, so you'd expect them to have some military personnel come over on a regular basis anyway.
Posted 3 years ago2020-11-26 22:55:05 UTC
in Review everything! [2nd edition] Post #344958
off-grid vertices in HL1 mapping

In my early years I would have frowned upon this, but now I wonder: what's the problem? Why shouldn't we be able to make tiny brushwork details? The reason why Hammer snaps them back is probably technical - either to make things easier for the compile tools, or so they can produce more optimal results, or to reduce problems caused by numeric (im)precision. Which reminds me of the 'Leak-o-matic' (I mean 'carve') tool. Carve with a cylinder and you'll get plenty of off-grid vertices, and multiple leaks as a bonus. But you'd probably get those leaks even without snapping. So remember kids: carve with care, and keep your vertices on the grid!

linerider (the game)
Posted 3 years ago2020-11-25 13:27:27 UTC
in Railroad swapper Post #344952
A path_track that has both a 'Next stop target' and a 'Branch target' will switch between these when triggered. By default, it'll point trains to the 'Next stop target', but after triggering the path_track, it will point trains to the 'Branch target'. Triggering it again will make it point to the 'Next stop target' again.

Pretty much like how a real railroad switch works: you 'trigger' it to switch it to another track, so that any train that comes by will be redirected to that track.
Posted 3 years ago2020-11-24 00:07:53 UTC
in Monstermaker enemies not hostile Post #344943
I did some monstermaker tests recently for a tool I'm working on, and I noticed the same. I think I've only seen it happen the first time a particular monster type spawned, so it might be some kind of initialization issue, but I didn't investigate it further.
Posted 4 years ago2020-11-20 14:02:00 UTC
in Need help with Activities and NPC coding Post #344908
The problem is that iSequence = LookupActivity ( NewActivity ); line at the bottom - that's overwriting the animation you've selected with a random idle animation. If I were you I would also simplify this code by creating a function that returns the name of the NPC's weapon, so you only need a single if/else statement that decides between "ref_aim_" + WeaponName() and "crouch_aim_" + WeaponName() (that's not exactly how you concatenate strings in C or C++ - right now I don't have time to look that up - but you should get the idea).

(I've also edited your post to fix the code formatting - for large code blocks, use triple ticks: ` ` ` code goes here ` ` `)
Posted 4 years ago2020-11-20 08:37:24 UTC
in Need help with Activities and NPC coding Post #344899
Did you look at the ACT_IDLE part in that grunt code? That's using LookupActivity(NewActivity), which will randomly pick one of the animations that are marked with that activity tag (if I understand things correctly). That's not what you want.

Instead, look at the ACT_RANGE_ATTACK1 and ACT_RANGE_ATTACK2 parts - those use LookupSequence("sequence name") to pick a specific animation based on the grunt's weapon and posture. That's what you want to do. So if the new activity is ACT_IDLE, and your NPC is holding an RPG, do iSequence = LookupSequence("idle_rpg"), if the NPC is holding a crowbar, do iSequence = LookupSequence("idle_crowbar"), and so on.
Posted 4 years ago2020-11-09 23:02:24 UTC
in TWHL Tower 2 Post #344841
Huh, is it that long ago already? I did start work on a floor, but abandoned it when it became clear that I couldn't finish it before the deadline... Anyway, looking forward to finally play this thing. Screenshots are looking very good. :)
Posted 4 years ago2020-10-21 21:14:18 UTC
in Programming video tutorials Post #344792
Looks promising! It's interesting to see what you're working on, too. :) I also like how you're using that dog to show 'emotion' and movement. Keep it up!
This post was made on a thread that has been deleted.
Posted 4 years ago2020-10-14 09:53:45 UTC
in Making Deathmatch Classic Maps in J.A.C.K? Post #344770
Go to 'Tools -> Options -> Game profiles' and create a new game configuration by copying your HL or HLDM configuration. Then:
  • Game tab: remove any .fgd files and add dmc.fgd instead (this file is included in the FGD collection here).
  • Directories tab: I think you only need to change the 'Mod Directory' to point at your Half-Life\dmc folder.
  • Textures tab: any .wad files you're using must either be part of DMC, or you'll have to distribute them alongside your map (you can embed textures into maps to make things easier for players). It's easier to only select DMC wad files for now.
  • Build Programs tab: you can use the same compile tools as for HL/HLDM, so no changes required here.
Finally, if you want to run your maps from the editor, go to the 'Run map' menu (by pressing F9 when a map is open) and make sure that the game is launched with the -game dmc parameter. In normal mode, that goes in the 'Additional game parameters' input. In expert/advanced mode, it goes in the 'Parameters' input of the game_exe command (which is typically located at the bottom).

I don't have DMC here to verify so I might be wrong on some of the details. Let us know if this works for you.
A 'few weeks' turned into a few months, but hey, it's finally here!

MESS is a Half-Life level compile tool that helps automating various tasks. It provides a templating system and several macro entities for creating template instances, which can be customized with a basic scripting system. Here are some of the things you can do with it:
  • Duplicating complex entity setups as if they were a single entity.
  • Covering terrain and other surfaces with props.
  • Turning a single brush into multiple entities.
MESS can be downloaded here (direct download link: mess_1.1.zip). For a full introduction, take a look at the readme and the entity guide. Also be sure to check out the example maps!
Here's what a template looks like, and how it can be instantiated:
Landmine templateLandmine template
Landmine instancesLandmine instances
There are also several example maps to get you started:
Loading embedded content: Vault Item #6451
I still have several other ideas I want to incorporate into this tool, such as a custom .fgd system (for creating entity 'aliases' for frequently used templates), a more general collision mask system (to make random level generation more viable), a viewer tool for seeing MESS expansion results in 'real-time', and perhaps support for external script files... but that's for later.

Please let me know if you find this tool useful, or if you encounter a problem with it, or if you have ideas for other features!
Posted 4 years ago2020-09-19 16:12:11 UTC
in Post your screenshots! WIP thread Post #344723
I'm working towards the first (beta) release of MESS. Currently working on some example maps:
macro_cover_examplemacro_cover_example
Other examples are about using macro_insert entities to easily reuse a monster warp effect, or using a macro_fill entity to fill a pool with leeches, or using macro_brush entities to create fences and railings that do not block bullets (without having to manually cover them with clip brushes). I think I'll make a rat-hunt example map as well, to demonstrate the power of recursive templates.

The only things left to do now are writing additional documentation and fixing a few issues here and there. Almost there! :)
It looks like you accidentally made that bone hidden. Try unhiding everything (Edit -> Unhide all, or Ctrl+Shift+H if I'm not mistaken).
Your compile/run commands probably look like this:
$csg_exe $bspdir/$file
$bsp_exe $bspdir/$file
$vis_exe $bspdir/$file
$light_exe $bspdir/$file
If so, change them to this:
$csg_exe "$bspdir/$file"
$bsp_exe "$bspdir/$file"
$vis_exe "$bspdir/$file"
$light_exe "$bspdir/$file"
Command-line arguments are normally separated by spaces, so without the double quotes a filename that contains spaces is interpreted as multiple arguments. Unfortunately, Half-Life itself won't load the map, even when using double quotes: hl.exe +map "$file", so you'll have to start Half-Life, open the console and type map "jack map". So yeah, it's easier to use filenames without spaces.
Posted 4 years ago2020-08-25 20:28:18 UTC
in GoldSource error - model stuck in wall Post #344647
More test results:
  • cycler_sprites do precache their model after reloading, so that is not what's causing them to disappear.
  • the brush-based entity 'hack' does not suffer from the reloading problem (tested with func_wall and func_illusionary). However, this requires another entity to precache the model, and that precaching must be done before the brush-based entity is initialized, otherwise HL with hang or crash while loading the map. This depends on the order in which the entities are stored in the .bsp file.
  • J.A.C.K. does not handle brush-based entities without brushes well - in some cases it crashes, in other cases it puts them at (0, 0, 0).
  • monster_furnitures are dropped to the ground after spawning.
  • env_sprite seems to work just as well as cycler_sprite, without the reloading problem.
So I now think that env_sprite is the best way to go. The only downside is that, because halflife.fgd marks its 'model' attribute as 'sprite' instead of 'studio', J.A.C.K. does not display the model (and Hammer just crashes when loading such map files).

One way to solve that is to add a custom entity (let's call it env_model) to the fgd, with a 'model(studio)' attribute. That would give you proper editor support. Then you'd need a custom compilation step that renames all 'env_model' entities in the .map file to 'env_sprite', before the other compile tools start processing the .map file.
Posted 4 years ago2020-08-19 09:07:43 UTC
in GoldSource error - model stuck in wall Post #344631
Why does nobody use monster_furniture...
That's... a good question! Time to update the entity guide? ;)

I did a little bit of testing, and after loading a savegame:
  • cycler_sprites are not restored correctly. That probably wasn't implemented because it's just a sprite-viewer test entity after all.
  • monster_furnitures are restored correctly. They're also seen as targets by the auto-aiming system, and bleed a little when hurt by explosives.
  • trigger_autos that did not remove themselves after firing are triggered again.
Posted 4 years ago2020-08-13 09:04:15 UTC
in GoldSource error - model stuck in wall Post #344619
Try using a cycler_sprite instead. Despite its name, it can also be used to render models, and it won't be solid when used that way.

It's also possible to use models with a few brush-based entities, such as func_train. On top of my head: create a point entity, change its classname to func_train, add a 'model' attribute and set it to the path of the model you want to use. If it's a model that's not normally precached, then you also need to add a monster_generic or cycler_sprite entity to your map that references the same model. That entity can be killed after the level has started, its only purpose is to force the game to load that model. A bit of a hack, but it works.
Posted 4 years ago2020-08-08 09:49:13 UTC
in Post your screenshots! WIP thread Post #344609
If my last screenshot was a bit MESSy... this time Hammer complained with 'Too many visible objects.'. I guess filling an area with 500 instances of a recursive template is not a good idea:
User posted image
So I'm working on some macro entities that can quickly cover a surface or fill a volume with instances. Here's the source map. The blue blocks on the left delimit template areas, the big grey cube is a macro_fill entity and the grey/yellow brushes behind that are a macro_cover entity:
User posted image
Here's what it looks like after it's been processed. The template areas have been removed, but their contents have been copied multiple times onto the non-NULL faces of the macro_cover entity and on the inside of the macro_fill entity:
User posted image
There's still a whole bunch of details to finish up, but the core functionality of MESS is pretty much there: creating templates (macro_template and macro_remove_if, or separate map files), inserting them at specific points (macro_insert) or using them to cover a surface (macro_cover) or to fill an area (macro_fill), and customizing them with an expression/scripting system.
Posted 4 years ago2020-08-06 11:42:30 UTC
in I have a serious issue with curved brushes Post #344606
With the selection tool enabled, clicking inside a selection box in any of the 2D views will cycle between resize, rotate and shear mode.
Posted 4 years ago2020-08-05 22:07:33 UTC
in how can i disable a momentary_rot_button? Post #344603
I was going to say 'use a multisource master', but apparently a momentary_rot_button just ignores that, unlike most other entities.

But perhaps you can fake it by disconnecting the button from its door with a trigger_changetarget, then making the button invisible with an env_render and showing a non-moving replacement button instead (func_wall_toggle)?
Posted 4 years ago2020-08-05 21:29:44 UTC
in Making a block disappear after using Post #344602
Various options:
  • If you don't need your entity again, then just kill it (quite a few entities support the 'killtarget' property).
  • Use a func_wall_toggle. Trigger it to make it disappear (or reappear).
  • Use an env_render to make your entity invisible.
Posted 4 years ago2020-08-05 21:16:56 UTC
in I have a serious issue with curved brushes Post #344601
There are various tools that you can use:
  • Shearing is quick and easy, but significant shearing results in 'thin' brushes.
  • With the clipping tool (shift+X) you can start with a larger brush and cut away parts until you get the desired shape. Press shift+X again to cycle between modes (remove right side, remove left side, keep both sides).
  • With vertex manipulation (shift+V) you can move each vertex or edge individually, create new edges (by selecting two vertices or two edges on the same face and pressing ctrl+F) and remove vertices (by dragging them onto other vertices). This is a powerful tool, but keep in mind that each face must remain perfectly flat - bent or curved faces are invalid. Brushes must also remain convex (e.g. no U-shaped brushes). Press shift+V again to cycle between modes (vertices and edges, vertices only, edges only).
  • When creating a brush, you can choose between a few different shapes. 'block' is the default choice, but 'arch' is probably more useful in this case. Keep in mind that it'll be facing towards you in the 2D view that you most recently clicked on.
If 'hollow circular object' means you want to create a curved pipe, those can be tricky and time-consuming to do by hand, depending on how many segments you want. I usually stick to 1 or 2 segments, with 1:1 and 1:2 shearing. I also keep vertices in the straight parts on a 2-unit grid, so 1:2 shearing and clipping won't produce invalid brushes. There are also a few tools out there to generate curved shapes, but I'm not sure if they can do hollow pipes.
Posted 4 years ago2020-08-02 14:27:30 UTC
in Post your screenshots! WIP thread Post #344584
@I have a plan: that's Goldsource, right? Looking good!

Stress-testing Hammer a bit with a custom tool and recursive templates:
User posted image
I don't think I want to compile this though...
Have you tried changing the CVOXFILESENTENCEMAX define in dlls/util.h?

As for music, I have no idea what could be causing that problem - all I can say is that I can't reproduce it. Copying that gearbox track into my valve\media folder and issuing either 'cd play 3' or 'mp3 play media/Prospero01.mp3' in the console works for me. Does it fail with other mp3's as well?
Posted 4 years ago2020-07-14 20:04:45 UTC
in How do i change the Weapon Damage? Post #344536
These values are not hard-coded, but stored in skill.cfg, which is a plain text file that specifies weapon damage, enemy health and a few other things.
Posted 4 years ago2020-07-10 12:18:40 UTC
in TWHL's Rat Problem Post #344522
I quite enjoyed your Hundred Heinously Hidden Buttons map, but somehow hadn't noticed your Rat Hunt map. Looks like a fun diversion for the coming weekend. :)

But... adequate health? Just how dangerous are these rats supposed to be?

A few technical notes:
  • The rat template can be simplified by removing the env_render and making the trigger_relay killtarget the cycler_sprite.
  • I think it's possible to make the counter system easier to adjust. Initialize the game_counters to the total number of rats in the map, then count down (by sending an 'off' message) whenever a rat is killed. This lets you match the counter limits with their corresponding messages, so you don't need to modify other messages when you add/remove one. The initialization can be done with a single game_counter_set, so there's only one number that needs to be adjusted. Disclaimer: I haven't tested this.
Posted 4 years ago2020-06-06 22:51:15 UTC
in Right way to set up counter + conditions Post #344374
A CD and manual even? You're also going to release it on-line, right? ;)

I wonder though, isn't there a risk that you'll get a cease-and-desist letter from whoever owns the Matrix IP?
Posted 4 years ago2020-06-06 22:49:17 UTC
in How do you "connect" .fgd code to model skins? Post #344373
The fgd maps names like 'Luther' and 'Slick' to numerical values for the 'body' attribute. If I understand correctly then that attribute, along with 'skin' and a bunch of others, should be applicable to every entity with a model. However, the game code for barney takes direct control over this body attribute, with 0 being used when his gun is holstered, 1 when it's drawn and 2 when he doesn't have a gun, so setting that attribute is of no use - it'll get overridden immediately. The code doesn't mess with the skin attribute though, so a custom skin should be possible without having to modify game code.
Posted 4 years ago2020-06-03 23:12:27 UTC
in Competition 39: The Buddy System Post #344359
I played through all of them, twice now. I'm impressed by just how much more content the other entries provided! hermanJnr.'s entry had some good surprises and cool sequences and generally worked pretty well. Burnerman56's entry had some good scenes and ideas as well, including good use of music and a few secrets sprinkled around, but relying on HL AI to stay alive long enough with so much combat is a risky thing and can result in some frustrating moments. Either way, I think both entries stuck to the theme very well, with a good balance between giving and receiving help.

I made some more notes so if any of you is interested in more detailed feedback (or if you want to give feedback on my entry), feel free to PM me. :)

@hermanJnr: the curved wall was done by creating a small and large cylinder, then vertex-manipulating tetrahedrons to line up with them. A bit tedious but fairly safe. The curved line was just a func_detail, so no risk of grid/leak issues. The lighting in the maintenance halls was mostly a combination of texture lights and chamfered edges to soften the transition between light and dark. I don't know how much of a difference Vluzacn's compile tools made compared to Zoner's, but from what I read it does come with some lighting improvements, so I think that helped as well.
Posted 4 years ago2020-06-03 23:08:33 UTC
in Right way to set up counter + conditions Post #344358
Heh, that's cool. :) Is this a singleplayer or a multiplayer mod?
Posted 4 years ago2020-06-01 22:52:19 UTC
in Competition 39: The Buddy System Post #344352
Almost there. :) Initiating wrap-up sequence in 3... 2... 1...

...and done. With less than an hour to spare. Phew.
Posted 4 years ago2020-05-31 22:41:15 UTC
in Competition 39: The Buddy System Post #344345
Only 25 hours left. No pressure! :crowbar:
Posted 4 years ago2020-05-30 22:09:45 UTC
in Right way to set up counter + conditions Post #344338
That's why I said you need to disable the countdown timer, see this post. The following changes should work (in theory - I haven't tested ;) ):
// Always check if we need to start an auto-reload countdown:
if (FBitSet(m_pPlayer->pev->flags, FL_FAKECLIENT) &&          // Is this a bot?
    (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0) &&         // and is it out of ammo?
    (m_flFreeammotime <= 0))                                  // and are we currently not waiting for an auto-reload?
{
    m_flFreeammotime = gpGlobals->time + RANDOM_FLOAT(1, 5);  // Then start waiting for an auto-reload.
}

// Always check if we need to perform an auto-reload:
if (m_flFreeammotime > 0 &&                                   // Are we currently waiting for an auto-reload?       <-- NEW!
    gpGlobals->time >= m_flFreeammotime)                      // and is it finally time to perform the auto-reload?
{
    UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "AUTORELOAD\n");    // Show a debug message.
    m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] += 99;            // Give the bot some ammo.
    m_flFreeammotime = 0;                                     // and stop waiting for an auto-reload.               <-- NEW!
}
Tip: proper indentation of the code makes it easier to see which blocks depend on which conditions.
Posted 4 years ago2020-05-30 19:25:44 UTC
in Right way to set up counter + conditions Post #344335
I don't know the rest of your code, so I can't tell whether this is the right place. I'll need to know at least in which function this is located, and in which 'blocks' it's located within that function (inside an if or else block, or part of a for or while loop body, etc.).

Either way, there is a subtle problem with this code: it will give the player ammo even when gpGlobals->time is still less than m_flFreeammotime, because only the UTIL_ClientPrintAll line depends on the if statement. This is how the compiler sees your code:
if (gpGlobals->time >= m_flFreeammotime)
    UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "AUTORELOAD\n");  // Only executed if the above condition is true

m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] += 99;  // Always executed
If you want to have multiple lines of code depend on an if statement, then you have to surround them with curly braces:
if (gpGlobals->time >= m_flFreeammotime)
{
    UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "AUTORELOAD\n");
    m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] += 99;
    // Both of these lines are now only executed if the 'if' condition is true
}
Posted 4 years ago2020-05-30 15:40:13 UTC
in Right way to set up counter + conditions Post #344332
What you're doing is only checking if it's time to auto-reload immediately after you decided the next auto-reload time. That's like looking at the clock after you wrote down the time, but then never checking the clock again.

Don't put the if (gpGlobals->time >= m_flFreeammotime) { ... } part inside the block that starts the countdown timer.
Posted 4 years ago2020-05-30 14:13:44 UTC
in Right way to set up counter + conditions Post #344330
That line doesn't start a countdown the way we humans would do a countdown. It's more like looking at the current time (which is, say, 9:30), deciding you want to go out after 5 minutes, and then writing down '9:35'. You only do that at the start - if you did that again at, say, 9:33, then you'd overwrite the original 9:35 with 9:33 + 5 = 9:38, which essentially just postpones things.

The real work happens in Think - that's similar to looking at the clock every minute or so to see whether it's 9:35 already. Is 9:30 at or past 9:35? No. Is 9:31 at or past 9:35? No. Is 9:32 at or past 9:35? No. ... Until finally at 9:35, the answer is yes, and you go out.

Computers are good at following orders, but they're not smart, so you have to be very precise with your instructions. 9:36 is also past 9:35, so a computer will happily decide to go out again. The same happens at 9:37, 9:38, and so on. Overwriting the original 9:35 with 0:00 won't help, because 9:36 is also past 0:00, so that's why you need an extra check: do I need to go outside? We people just 'know' what we want, but for a computer you really need to spell out all those little details.

You can make the code easier to understand by creating a few small functions:
void startAutoReloadTimer(float seconds)
{
    if (!isAutoReloadTimerEnabled())  // Only schedule a new auto-reload if we're not waiting for one already.
        m_flAutoReloadTime = gpGlobals->time + seconds;
}

bool isAutoReloadTimerEnabled() { return m_flAutoReloadTime > 0; }

void stopAutoReloadTimer() { m_flAutoReloadTime = 0; }
and use those throughout your code:
if (isAutoReloadTimerEnabled() && gpGlobals->time >= m_flAutoReloadTime)
{
    autoReload();
    stopAutoReloadTimer();
}
A simpler variant is to just set m_flAutoReloadTime to a really big value, like 'next year'. I prefer the above approach however, because it's more obvious that the timer can be stopped.
Posted 4 years ago2020-05-30 00:10:15 UTC
in Right way to set up counter + conditions Post #344324
Starting the countdown can be done as following (you already did this in your second sample). This will set the next auto-reload time between 5 and 10 seconds in the future:
m_flAutoReloadTime = gpGlobals->time + RANDOM_FLOAT(5, 10);

Then you periodically check whether it's time to do auto-reload. This goes in your entity's Think function:
if (gpGlobals->time >= m_flAutoReloadTime) { autoReload(); restartCountdown(); }

If you don't want to start another countdown after auto-reloading, then you'll have to disable the countdown check. This can be done by adding an extra boolean variable that indicates whether the countdown is enabled:
if (m_bIsCountdownActive && gpGlobals->time >= m_flAutoReloadTime) { autoReload(); m_bIsCountdownActive = false; }
Don't forget to set this variable to true when you start another countdown.
Posted 4 years ago2020-05-29 18:56:17 UTC
in Right way to set up counter + conditions Post #344318
Checking whether m_flstufftime is 0 or less only makes sense if it represents the time that is left until something needs to be done. In that case, you'll need to decrement it periodically by however much time has passed. But you're incrementing it. It's also unclear in what context this code is being executed.

I'm not too familiar with the HL SDK, but it looks like the easiest way to do this is to execute dosomething in a Think function, and to schedule that function by setting pev->nextthink to the current time + however many seconds you want to wait.

If your entity already needs to perform other work periodically, then here's what I would do: when starting the countdown, set m_flstufftime to the current time + the number of seconds to wait. m_flstufftime now represents the time at which dosomething should be executed. Then, in your entity's Think function, check whether the current time has surpassed m_flstufftime. When it has, execute dosomething, and disable or restart the countdown logic to prevent dosomething from being executed continually from that moment on.

Other notes:
  • RANDOM_FLOAT's first argument is the lower bound, so you should swap the arguments in your first sample. I'm not sure why you need randomness though?
  • m_flstufftime is not a very descriptive name. Something like m_flCountdownTime would be more clear.
  • (while) loops are executed as fast as possible, they're not meant for code that should be 'spread across time'.
Posted 4 years ago2020-05-20 09:37:05 UTC
in How to create Pak files Post #344247
Do any of those filenames contain non-ASCII characters, such as letters with an accent or a tilde?
Posted 4 years ago2020-05-10 13:14:56 UTC
in item_antidote in TFC Post #344196
I was about to give the same answer, but decided to check the source code to be sure, and found that antidotes do have a function. The poison and nerve-gas damage types apply damage over time, but having an antidote will stop that effect after a few seconds. The HEV will notify you when an antidote is used.

That's HL bytheway, I don't know whether this behavior has been removed in TFC.
Posted 4 years ago2020-05-09 19:24:30 UTC
in Post your screenshots! WIP thread Post #344187
I'd say that both koe1's and abbadon's work looks pretty impressive. And UrbaNebula's The Core as well. And Admer456's work on terrain... good stuff. :)
Posted 4 years ago2020-05-09 19:21:28 UTC
in My first map does not work Post #344186
The Half-Life engine isn't very well suited for large open spaces. It's possible to get a map like this to work, but it requires some understanding of how this engine works.

Maps must be enclosed spaces
First, HL maps must always be enclosed spaces. Whenever you see sky in a map, you're actually inside a room whose roof and wall brushes have the special 'SKY' texture. In this case, the quick and easy way is to surround the whole map with a giant 'SKY' box, but you'll likely just get long compile times and bad performance in-game. It's much better to design your map up-front as a series of rooms and corridors, where a street is just a large corridor with a 'SKY' roof and walls that look like houses. Just look at the official CS maps to see how that works in practice.

The reason for this is that many years ago, when the Quake engine was made, computers were far less powerful. They couldn't render too many polygons, and determining which ones were visible also took a lot of time. So they came up with a tool that divided maps into separate areas, and it would calculate up-front which areas were visible from which other areas. Now all the engine had to do was look up this information so it knew which areas it needed to draw. But the level-designer still needs to carefully block visibility from one area to another for this approach to be useful.

Turn small brushes into func_detail's or func_wall's
That leads me to the second point: there are lot of small brushes in your map. All of these affect this area division process, causing areas to be split up into many more smaller areas. This causes a lot more work for the compile tools and makes the process a lot less efficient. In general, you'll want to turn small detailed brushwork into func_detail's or func_wall's. And for things like that motorcycle (which looks awesome btw!) it's better to create models instead. Models can be more detailed and are easier to render, at the expense of lighting quality.

Avoid rotating brushes
I also see a lot of rotated brushes, with vertices not aligned to the smallest grid size. I'm not sure, but I think the compile tools will snap those to the nearest point on the grid, which can cause malformed faces, leaks and other kinds of problems. There's a reason why many HL and CS maps are relatively blocky and grid-aligned.

Too much detail for an open space
Finally, large open spaces take a lot of polygons to draw. Lots of small details also take a lot of polygons. There's only so much that the HL engine can handle before you'll get performance issues. In this case, I suspect that the player will never get close to those far-away houses, so I would turn them into simple blocky shapes, without any detailed brushwork.

It's a good idea to first build the general layout of a level and test that in-game. Then you gradually add more detail, while occasionally testing in-game to see how it looks and whether performance is still ok.
Posted 4 years ago2020-05-02 18:58:11 UTC
in Competition 39: The Buddy System Post #344161
Yeah, what am I doing here all of a sudden? :confused:

I have been lurking a bit here recently though. Did some work for the teleportation competition a while ago, and later for TWHL Tower 2, but I didn't have enough inspiration for the first, and ran into some technical issues for the second. But this time I've got a clear picture of what I want to make, so I felt I was ready to post something.

Here's a work-in-progress screenshot:
User posted image
I'm going for a high-tech test environment style. The main room here is mostly done in terms of layout and coloring. Next step is to create a few additional rooms, then some scripting to get the main gameplay up and running. Then it's time for lighting and texture improvements, and maybe some finer details, depending on how much time I've got left.
Posted 4 years ago2020-04-28 21:36:32 UTC
in Competition 39: The Buddy System Post #344154
I might be working on something.
Posted 15 years ago2009-10-22 18:46:36 UTC
in c++ again Post #274738
To respond to the original question: in C++, you'd use std::string for things like this. Makes programming in it a little easier.

Also, string literals (the "abcdef" in your 'char *word="abcdef"') are immutable: so you can't use that pointer to modify the string it points to.

As for languages, I used to be a big fan of C++, but now that I've used it for a few years, and now that I've gotten to know a few other languages... Let's just say I'm not that fond of it anymore. I'm using Python a lot more these days. It allows me to focus on what I actually want to build, rather than making me wrestle with tedious language details first. Ah well, each language has it's strong and weak points. In the end they're tools - pick the one that's best for the given job.
Posted 15 years ago2009-05-01 15:53:00 UTC
in TWHL's death? Post #266294
I think that many internet communities die or at least shrink over time. Certainly the ones that are based on an aging subject such as Half-Life mapping. From what I can tell, TWHL's main reason of existence has shifted from being a Half-Life level sharing place to, well, a chatter-box for the regulars. Of course, that's exaggerated, but there aren't that many really active mappers around anymore, right?

And then, to keep things alive, the site gets revamped, much like what happened at Snarkpit. But the core activity has shrunk already, and a facelift doesn't change that. People didn't come to this site because it looked so pretty, they came to share their maps. They still do, but it's less than a few years ago. You can encourage that (competitions?), but you can't enforce it.

In other words, it's been a great time, but life goes on. On to new things to explore. :)
Posted 15 years ago2009-04-27 11:16:48 UTC
in alan Post #266043
Sounds nice. :) Japanese sounds quite different from Mandarin and Tibetan (?) though. I like Tselang Lhamo more.

I actually started playing erhu a while ago. Not that I'm good or anything, but it's fun. :)