Forum posts

I just finished a tutorial (with lots of pictures) for WadMaker: Making textures with WadMaker. Feedback is welcome. :)
Posted 1 month ago2021-09-21 20:36:50 UTC
in How to make a random generator? Post #345947
Yes, that's also possible. The catch is that the button press should enable and then quickly disable the beam, so that it can only trigger one random entity, instead of continuing to trigger random entities. Here's how you can do that:
  1. In the env_beam's properties, disable the 'Start On' flag and enable the 'Toggle' flag, so you can disable the beam by triggering it again.
  2. Set the env_beam's 'Life' property to 0.1 seconds - or longer, if you don't want it to be reusable too soon.
  3. Create a multi_manager, and make it trigger the env_beam twice. First with a delay of 0, then with a delay that matches the env_beam's 'Life' property.
  4. Set the 'Target' property of your func_button to the name of this multi_manager.
Posted 1 month ago2021-09-18 17:36:55 UTC
in How to make a random generator? Post #345938
Unfortunately Half-Life doesn't provide something like a trigger_random entity, but eventually some mapper(s) came up with a technique to trigger random entities. By using a high-damage env_beam that randomly targets one of several info_targets, and by placing func_buttons in front of those targets, you can trigger different entities depending on which info_target the beam decides to strike. It's described in more detail in the following tutorials: A Random Event Generator and Random entity triggering.

If you want to trigger multiple things at the same time, you can give them the same name (so they'll always be triggered together), or you can trigger a multi_manager, an entity that can trigger multiple entities (see Tutorial: Multi_manager for more info).
SpriteMaker is now available, and WadMaker has a few improvements and bugfixes (and some example configurations for setting up automatic Gimp and Aseprite file conversions)! See the first post in this thread for download links and a full changelog.
As far as I understand putting options/switches before (positional) arguments is a fairly wide-spread convention. C#'s standard library doesn't have anything for command-line parsing, so it's a trade-off between managing a dependency versus writing your own.

I marked your Github issues as enhancements. I think they're all good ideas that shouldn't take too much time to implement. Right now I'm working on finishing up SpriteMaker but I think I can spend some time on a MESS update after that.

Did you manage to resolve your expression error? One way to debug things would be to add a 'dummy entity' inside a template, using its attributes for 'logging' things. I also find it useful to have a compile mode in JACK that only runs MESS and then opens the modified map file with JACK.
You'll need to specify a log level (off, error, warning, info or verbose). Try setting it to warning or verbose and see if that gives you enough information. If that doesn't help, then what sort of error are we talking about? What does the expression look like?
Here's the documentation for macro_remove_if:
Used inside templates. When an instance of a template is created, anything inside the bounding box of this entity is excluded from that instance if the removal condition is true.

  • Removal condition (condition) - The condition that determines whether the contents of this entity must be excluded. none (empty) and 0 will prevent removal.
So yeah, you put it around brushes and entities just like you do with macro_template. The condition attribute behaves the same as other attributes, so you'll need braces if you want to use scripting. Even though that's almost always what you want, I decided that consistent attribute behavior was more important than shaving off a few braces. Both macro_template and macro_remove_if only apply to things that are fully inside their bounding box.

For an example on how to use macro_remove_if, take a look at examples\templates\rathunt\message_system.rmf. It's a template map that omits certain entities based on the attributes of the instance-creating entity, and it also uses a macro_remove_if to limit the recursion of a sub-template.

The problem with scaling is that it also affects the 'scale' attribute of point entities. But I could split that up into two attributes: one for entities ('Scale') and one for geometry ('Geometry scale'). That would also solve the problem where you want to scale up geometry but not entities. As for negative scales, that's currently not working correctly, I'll have to look into that.

As for producing rotated instances, that's exactly what macro_insert's 'Angles' property is for. Can you show me the results you get and what you expected to get? As well as the attributes of the macro entities involved?
I did investigate Gimp's file format a while ago, but the main problem is that it doesn't contain a flattened image. I'd have to implement layer compositing, but that's a fair bit of extra work. The same problem applies to Aseprite and Paint.NET files.

But WadMaker can be configured to use external (command-line) conversion tools, and there seem to be several tools that can convert .xcf files (Gimp's batch mode, xcf2png, ImageMagick, Irfanview). So if you can get one of these tools to work, then it's just a matter of creating a wadmaker.config file in your source image folder and adding a line like the following (where {input} is the full input .xcf path, and {output} is a .png file in a temporary folder):
*.xcf    converter: '"C:\Tools\XcfConverter.exe"' arguments: '-in="{input}" -out="{output}"'
The above is just an example. Once I'm done with SpriteMaker I'll update the documentation with .xcf and .aseprite file conversion examples.

As for automatic resizing, if you're talking about allowing images of arbitrary size then I don't think that's a good idea due to quality loss. But if you're working with high-res source images (say, 2x as large) then I guess a scaling factor setting could be useful. I'll think about it. For now, you could perhaps use the above converter approach to resize your images.
You don't need to do this. The compile tools will combine all world brushes into a single mesh and will remove any faces on the outside, so it's no problem if brushes are sticking out. That's also why decompiling gives such poor results: there's just not enough information in a bsp file to reconstruct the original brushwork.

1. If you really want to, you can use the vertex manipulation tool (Shift + V) to move the corners of your floor brush around. This mode also lets you create new edges (by selecting two existing vertices (white) or edges (yellow) and pressing Ctrl + F, or merge vertices by dragging them on top of each other. This is an advanced tool however, and using it incorrectly can produce invalid brushes, so use with care.

2. Judging from your screenshot, I can't tell whether you've got brushes with off-grid vertices, but you do have several points where the corners of two brushes join up next to the edge of another brush. That may result in tiny cracks between brushes, which is probably what's causing this 'ambiguous leaf node' error. That's one reason why I'd recommend sticking to a coarser grid size when working with 'structural' brushwork like this, and to stick to 'safe' slopes like 1:2, 1:4, etc, as that makes it easier to ensure that junction points like that are still perfectly aligned with the grid.
Posted 3 months ago2021-06-26 20:17:03 UTC
in Half-Life: Direct edit of compiled BSP files Post #345704
BSPEdit allows you to edit entity data in bsp files. You'll need to be careful to keep the data properly formatted though. It also saves bsp files in-place, so it's a good idea to make backups first.
Posted 4 months ago2021-06-13 22:41:36 UTC
in Duplicate faces when rendering HL1 BSP map? Post #345699
That's due to how sky brushes are compiled - it's not a bug in your code. Apparently sky brush surfaces are turned into double-sided faces - which is why several faces in your map are on opposite sides of the same plane, using the same vertices but in reverse order. Another quirk is that, unlike with other brushes, the tools also produce faces for the 'outside' surfaces of those sky brushes. Maybe there's a good reason for this behavior, I'm not sure.
WadMaker 1.1 is now available!
It can be downloaded here. For more information, see the readme.

New features:
  • Added support for Photoshop files (.psd, .psb) that have been saved with 'maximize compatibility' enabled.
  • Added support for Krita (.kra) and OpenRaster (.ora) files.
  • Added support for creating and extracting decal wad files (decals.wad).
  • Updated the wadmaker.config system to apply all matching rules (with more specific rules overriding less specific ones).
  • Console output is now logged to a file (only in create-wad mode). This can be disabled with a command-line option.
  • Fixed that removing an image with an uppercase name would cause updating a wad file to fail.
  • Fixed that water color was accidentally black by default.

WadMaker will automatically switch to decal mode when the ouput wad file name is 'decals.wad', and it expects input images to have an alpha channel - which it will use to create the decal texture. The average color of the input image is used as decal color. If you're not sure what format is expected, then first try extracting a decals.wad file, and take a look at the extracted images. It's also possible to enable grayscale input with a wadmaker.config setting - in that case you should also specify the decal color in the settings file.

As for Photoshop files, not all compression methods are supported because I could only find test files with raw and RLE compressed composite images. So please let me know if certain files don't work. I can add support as soon as I get some files to test with.
Posted 5 months ago2021-05-21 12:34:46 UTC
in How to make an explosive crate? Post #345658
Try a (much) larger value. The explosion magnitude affects both the amount of damage and the damage radius (apparently the radius is 2.5x the magnitude value). Also keep in mind that explosions do less damage to entities that are further away.
Posted 5 months ago2021-05-21 11:06:23 UTC
in How to make an explosive crate? Post #345656
A func_breakable with its 'Explode Magnitude' set to a value higher than 0 should do the trick.
If you're talking about writing custom game code, then the wiki here contains a guide that looks pretty comprehensive: Half-Life Programming: Getting Started. What exactly do you want to achieve?
always thought "that's way too much for me" (I was mostly used to CS mapping).
I also started out as a mapper, years ago. I eventually started experimenting with the game code and I somehow managed to make the MP5 launch a grenade with each shot, but I couldn't really do much else. Now, years later, I do programming for a living... So yeah, give it a go, and don't get discouraged if things seem complicated at first. Feel free to ask for help whenever you're stuck. :)
Thanks! Don't hesitate to ask if you have questions or feedback. :)
Disclaimer: I'm a bit of a perfectionist, so don't take what I'm about to say too seriously! ;)

This is basically a text-only Powerpoint presentation. A slideshow can be an interesting way to provide an optional piece of lore. But here, it's essentially a slow, boring cut-scene with no skip button, with a nerve-wracking humming sound in the background and blurry text that's barely readable. The text itself is fairly long-winded.

So the background story is that there's this 'SDI' laboratory that's using prisoners like you as test subjects, and you're about to escape their facilities. How do you tell that story in an interesting way? By letting the player experience the story. Have them start out in a cell-block: that immediately tells them they're a prisoner, and gives them a goal: to escape. Make the walls look like a modern laboratory, add windows that overlook test chambers, put appropriate signs on the walls, and players can now figure out on their own that they're in a test facility. A big 'Space Dynamic Incorporated' logo in a lounge somewhere tells them the name of the place. And don't just throw enemies at the player: let some alarms go off first. Let them know that their escape has been detected and that security is on their way. Make it part of the story!

My overall impression: the architecture, texturing and lighting are very basic. Rooms are blocky, with almost no detail, and the furniture that is present is out of proportion. Most of the rooms do look like they have an actual purpose, but the lack of detail and the somewhat illogical connection between the rooms doesn't make it feel like a realistic place. The dead grunts and scientist, and the zombies and houndeyes make it feel like a standard Half-Life disaster scenario, there's no sign of a custom story.

Enemy placement suffers from a common problem in that most enemies are just passively waiting for the player to show up. It makes the first rooms feel a bit dull. The grunts on the other hand are actively invading the place, which is a good change of pace. In general I felt there were too many enemies compared to how much ammo the player had, and putting grunts on high ground so early on in a level seems unfair. Then again, they felt easier to kill and less damaging than standard HL grunts. I'm not sure whether that's a good thing: how are you going to ramp up difficulty in later levels if you already need this many grunts so early?

I kinda like the idea of having to charge into a room to grab a powerful weapon, but I don't think it worked well here: the shotgun is barely visible and the houndeyes are quickly grabbing the player's attention anyway. The same goes for the closet on the side: the ammo and armor there give you a major advantage, but that's just not visible from the outside.

Other notes:
  • The slow movement speed was quite annoying. Having to hold a button to run isn't such a great idea for a fast-paced shooter. I think it's interesting how you managed to implement it, but it's also easy to break when changing keyboard bindings.
  • Instakill barriers are frustrating, especially when they don't look like they would kill you instantly. Just let the steam apply some burning damage and push the player back. Also, a pipe would (hopefully) never be placed like that in real-life!
  • The textures in the first room (old, industrial) don't match the furniture (cubicles, desks).
  • The scientist is partially inside the table.
  • The doors are frustrating: their keycard locks often collide with the player, causing them to close again immediately, and it takes a long time before they open again.
  • The tripmine doesn't get triggered by the houndeyes - that looks like a bug. However, I do like how you can use the houndeyes to blow up the mine with their sonic attack, and how a quick-thinking player can use the explosive crate to their advantage.
  • The large crate in this room doesn't fit through either door. Logic mistakes like this are not uncommon in maps, but they're a bit jarring once you notice them.
  • The HEV not working felt like a bug. It's probably a good idea to first introduce the body armor pickup before showing a HEV charger (if you need to show one at all).
  • The weapon closet texture scaling looks strange, and parts of the text look poorly copy-pasted. Why is the MP5 hidden behind the sign?
  • The reception hall provides the most interesting combat, but players probably end up camping in the doorway, or they find their way to the closet only to continue camping there. I don't think the layout does a good job of forcing the player to make interesting decisions.
  • In the concrete alley, having a grunt launch contact grenades from a high place around a corner... I'm not sure I would classify that as 'fun'.
  • The gap between the sandbag walls looks passable, but the player is blocked by an invisible wall. If something is impassable then it should clearly look impassable to prevent frustration.
  • The 'Leave game' text in the menu is messed up somehow.
  • The download contains a lot of models and sound files. Are all of these custom? If not, you may want to remove them to reduce download size.
  • The same goes for the screenshots, there's no need to include them. But if you do want to, then save them as jpg or png files to reduce filesize.
I hope this proves useful to you, and that I didn't sound too harsh!
Judging by a previous question of yours, and by the paths in your compile log, you're working on a mod, right? Did you verify that the bsp file is actually located in the Half-Life\yourmoddirectory\maps directory (where yourmoddirectory is the name of your mod's directory)? And are you starting hl.exe with the -game yourmoddirectory argument (you can also start your mod through Steam, which does the same thing)? If you're not doing that, then you're running the base game Half-Life (not your mod), which will only look for bsp files in the Half-Life\valve\maps directory.

You should also put any custom wad files you're using in your mod's directory.
You've got several invalid brushes. It looks like you've been using vertex manipulation. That's an advanced tool that can easily produce invalid shapes, so it's better not to use it until you have a better understanding of how to keep a brush valid. Use the clipping tool (Shift+X) instead, or the shearing tool (click on a selected brush in a 2D view to cycle between resize, rotate and shear modes).

The texture scales on your brushes vary wildly. It's often a good idea to keep them consistent (most textures are designed to be used with scale 1). This is probably caused by the various texture-locking modes that J.A.C.K. has enabled by default - I usually disable them.

Your func_door_rotating's don't have origin brushes. I replied to your question about that, but what I didn't mention explicitly is that an origin brush must be part of an entity. Normally you'd create both the visible brushes and the origin brush, select all of them, and then turn them into an entity. You already have a func_door_rotating entity, so in this case you'd create an origin brush, then select both the func_door_rotating and the origin brush, then press the 'To Entity' button (Ctrl+T), and select 'Yes' when it asks you to add the selected solids to the existing entity.

As for your map not loading, what exactly do you mean with 'it doesn't load properly'? Did you check whether the bsp file got copied to the right maps folder? What happens when you start Half-Life manually and type map roomone in the console?
WadMaker & SpriteMaker are finally finished!
It can be downloaded here. For more information, see the readme, or check out the Making textures with WadMaker tutorial.

These command-line tools can turn a directory full of images into a Half-Life wad file or into a directory full of sprites - just drag the directory onto the right tool. They can also extract textures from wad and bsp files, remove embedded textures from bsp files and convert sprites back into images.

WadMaker and SpriteMaker directly support png, jpg, gif, bmp and tga files, as well as Photoshop (psd, psb) and Krita files (kra, ora), and can be configured to call external conversion tools for other formats (example configurations for Gimp and Aseprite files are included). Both tools will automatically create a suitable 256-color palette for each texture or sprite. They will also apply a limited form of dithering, which can be disabled if necessary. For transparent textures and sprites, the alpha channel of the input image is compared against a configurable threshold, but it is also possible to treat a specific input color as transparent. For water textures, the fog color and intensity are derived from the image itself, but they can also be specified explicitly. Texture-specific settings can be overridden with a plain-text wadmaker.config file in the images directory. Common sprite settings such as orientation and texture format can be set within filenames, other settings can be overridden with a spritemaker.config file.

Why did I make these tools? First, I was investigating the various Half-Life file formats anyway. Second, I wanted a faster workflow than Wally and Half-Life Texture Tools (for me, running a batch file is faster than opening a GUI tool, dragging files around, saving a wad file, and closing the GUI tool). And finally, investigating various approaches to color quantization and dithering, and reading up on color spaces and color perception turned out to be very interesting.
Changes in v1.2:
  • Workflow: converts directories full of images to directories full of sprites, similar to how WadMaker works. Can also convert sprites back to images.
  • Efficiency: only modified files and settings are processed.
  • Configuration: common settings like sprite orientation and texture format can be configured within an image's filename. Other settings can be specified in spritemaker.config files.
  • Flexibility: accepts various image formats (png, jpg, gif, bmp, tga), Photoshop files (psd, psb) and Krita files (kra, ora). Input images can be true-color and can contain transparency, SpriteMaker will automatically generate a suitable palette. Support for other file formats can be enabled with converter rules (a global spritemaker.config file with example rules for Gimp and Aseprite files is provided).
  • Animation: animated sprites can be created with numbered image sequences, spritesheets and/or gif files.
New features/changes:
  • Added support for a global configuration file (a wadmaker.config file in the executable's directory). Global rules always apply, unless overridden by a local config file.
  • The provided global config file contains example rules for converting Gimp and Aseprite files and instructions on how to enable them.
  • Custom converters are no longer forced to output png files, the output file extension must now be specified in the converter arguments.
  • Custom converters can now also use {input_escaped} and {output_escaped} placeholders, for when backslashes need to be escaped.
  • Fixed a problem where processing transparent images with very little color variation could fail with an 'At least one color must be provided.' error.
  • Fixed that the dither-scale setting was not parsed correctly, so it could only effectively be set to 0 or 1.
  • Fixed that WadMaker would fail to create a wad file if the output directory did not exist.
  • Fixed that mipmaps were not extracted correctly.
  • Fixed some cases where WadMaker would fail to create a log file or a directory.

Changes in v1.1:
New features:
  • Added support for Photoshop files (.psd, .psb) that have been saved with 'maximize compatibility' enabled.
  • Added support for Krita (.kra) and OpenRaster (.ora) files.
  • Added support for creating and extracting decal wad files (decals.wad).
  • Updated the wadmaker.config system to apply all matching rules (with more specific rules overriding less specific ones).
  • Console output is now logged to a file (only in create-wad mode). This can be disabled with a command-line option.
  • Fixed that removing an image with an uppercase name would cause updating a wad file to fail.
  • Fixed that water color was accidentally black by default.
Posted 5 months ago2021-05-15 20:29:32 UTC
in Origin brush Post #345611
An origin brush is just a normal brush that's covered with the special 'ORIGIN' texture. The center of the brush determines the origin of the entity that it's part of - the origin brush itself is then discarded by the compile tools. If a rotating entity doesn't have an origin brush, its origin will be 0,0,0 (the center of the map), which often makes it look like it's flying all over the place.
Posted 5 months ago2021-04-28 23:15:29 UTC
in Where and When do i use Hint brushes? Post #345577
Hint brushes give you some control over how a map is split up into vis nodes by the compile tools. The 'HINT' side creates a new splitting plane, the 'SKIP' sides are ignored. In some cases you can improve performance by strategically breaking up nodes. Personally I think they're rarely needed if you keep limiting visibility in mind when designing a layout.

Here's a very crude example, showing a U-shaped corridor from above:
┌──────┐                ┌──────┐      ┌──┬───┐      ┌──────┐      ┌──┬───┐
└──┐   │  splits into:  └──┬───┤  or  └──┤   │  or  └──┬───┤  or  └──┤   │
┌──┘   │                ┌──┴───┤      ┌──┴───┤      ┌──┤   │      ┌──┤   │
└──────┘                └──────┘      └──────┘      └──┴───┘      └──┴───┘
As shown above, there are multiple ways in which this corridor can be split up into vis nodes. In the first 3 cases, every node is visible from any other node. But in the last case, the top-left node is not visible from the bottom-left node, and vice versa. With a hint brush, you can force the compile tools to produce that particular space partitioning.
Posted 5 months ago2021-04-26 20:40:57 UTC
in how can i emit a sound when selecting a weapon? Post #345564
You're returning from the function on the first line (return DefaultDeploy...), so the second line (EMIT_SOUND(...) is never executed.
Posted 6 months ago2021-04-07 14:48:07 UTC
in Help me, Lords of coding!! Post #345517
You may want to read Shephard62700FR's post more carefully, because there are two problems with your code:
  • it's immediately giving players a 15-seconds double-damage bonus when they spawn, instead of initializing the bonus-expiry time to -1.0f.
  • it's not giving a double-damage bonus when the damage-doubler item is touched, it's only checking whether the player currently has a double-damage bonus.
It's also not preventing the player from picking up another damage-bonus item if they already have an active damage bonus.

As for applying the damage bonus, FireBulletsPlayer is a CBaseEntity member function, so it doesn't know about CBasePlayer fields like m_flDoubleDamageBonusTime (it can be called on any entity, after all). One way to work around that is by creating a virtual float GetDamageBonus() function in CBaseEntity that returns 1.0f, but which you override in CBasePlayer to return 2.0f if HasDoubleDamageBonus() is true (you can look at the CBaseEntity::IsPlayer and CBasePlayer::IsPlayer functions for an example of how a virtual function can be overridden in a child class). You can then use that function inside FireBulletsPlayer as following:
pEntity->TraceAttack(pevAttacker, gSkillData.plrDmg9MM * GetDamageBonus(), vecDir, &tr, DMG_BULLET);

Some of the other weapons call TraceAttack directly, and since weapons contain a pointer to the player (CBasePlayer* m_pPlayer), you should be able to obtain the damage factor for them with m_pPlayer->GetDamageBonus(). For explosives I think you'll need to look at the RadiusDamage function, probably using CBaseEntity::Instance(ENT(pevInflictor))->GetDamageBonus() to get the damage bonus, if I understand how that works correctly.
Posted 6 months ago2021-04-04 15:45:05 UTC
in Map loading problem - Not spawning where I expect Post #345504
It's about relative positioning, not absolute coordinates. Info_landmarks act as anchor points. When a level transition occurs, entities are repositioned in such a way that their relative position towards the info_landmark in the new map is the same as their relative position towards the info_landmark in the old map.

Imagine a level transition that takes place in a corner with a vending machine in the middle. To a player, it looks like there's just one corner and one vending machine, but in reality, both maps contain their own corner and their own vending machine. Of course, the illusion only works if both corners look the same and if both vending machines are in the same relative spot in each map. Now when a level-designer sees both maps, they can easily tell how the maps are connected, because those vending machines are so recognizable (they're 'landmarks'). That's pretty much how the game looks at info_landmarks.

If you still can't get it to work, then maybe you can upload both maps to the vault here so I or someone else can have a look.
Posted 6 months ago2021-04-04 14:39:28 UTC
in Make "skill" higher than 3? Post #345503
If you search for g_iSkillLevel, you'll see that the CGameRules::RefreshSkillData function in gamerules.cpp forces the skill-level between 1 and 3 before it looks up skill-specific health and damage values. But there are also a few places throughout the game-code where the skill-level is checked specifically, so it's a bit more complicated than just increasing the maximum skill-level value.
Posted 6 months ago2021-04-04 14:22:59 UTC
in Critical HELP -> Changing dialogue times Post #345502
If you can find someone who knows how to do this, then sure, that would be easiest.

If not, then you could learn how to do it yourself using the tools I mentioned. For example, if you decompile the first tutorial level, t0a0.bsp, and open up the resulting .map file in J.A.C.K., then you'll find a trigger_once in the middle of the first room. This triggers a multi_manager named intromm. When you look at the properties of that entity (press the SmartEdit button so you can see the raw keyvalues) then you'll see that it triggers multiple other entities, each at a specific time:
targetname   intromm -- the name of this multi_manager
intro        .5      -- someone at Valve forgot to remove this, because there's no entity with the name 'intro'
td1          15      -- the door to the HEV suit room
td1l         14.5    -- the light above the door to the HEV suit room
holo1light   0       -- the hologram light
sent_intro   0       -- the scripted_sentence entity for the hologram welcome speech (sentence: !HOLO_WELCOME)
sent_button  14.5    -- the scripted_sentence  for the hologram speech about buttons (sentence: !HOLO_BUTTON)
butlight     15.1    -- the light above the button in front of the hologram
butsprite    15.2    -- the twinkling sprite that shows up above the button
J.A.C.K. can display arrows between entities that trigger each other, but unfortunately that doesn't work for multi_managers. Fortunately J.A.C.K. does have a way to search for entities with specific names: in the menu, go to Map -> Entity report, then in the Filter area of that window, enable 'by key/value', enter 'targetname' as key and the name of the entity you're looking for as value.

In this case, we can see that the first scripted_sentence is triggered immediately, with another shorter speech triggered after 14.5 seconds, along with a door and some lights and sprites. If your translated speech has a different duration, then you'll have to modify all those 14/15 second delays. In BSPEdit, search for multi_manager entities until you find the one with the same targetname (in this case that's the first multi_manager). Here's what it looks like in BSPEdit:
"origin" "-1328 -1484 -4"
"butsprite" "15.2"
"butlight" "15.1"
"sent_button" "14.5"
"sent_intro" "0"
"holo1light" "0"
"td1l" "14.5"
"td1" "15"
"intro" ".5"
"targetname" "intromm"
"classname" "multi_manager"
The key/value order is different, but that doesn't matter. Now change the 14/15 second delays to something suitable and save the map. Just be sure not to remove or add any double-quotes, otherwise Half-Life won't be able to read these entities anymore.
Posted 6 months ago2021-04-03 20:45:01 UTC
in Critical HELP -> Changing dialogue times Post #345498
BSPEdit lets you to modify entity data inside .bsp files. If it's difficult to find which entities you need to change then it may be useful to decompile the maps, so you can look for the right entities in Hammer or J.A.C.K.
Posted 6 months ago2021-04-01 09:47:07 UTC
in Post your screenshots! WIP thread Post #345493
That's some high-quality mapping there, Andy_Shou! I like how detailed it all looks. The lighting looks very good too. I'm definitely looking forward to a release.

Good luck with the home-schooling bytheway!
Posted 7 months ago2021-03-23 10:08:58 UTC
in Presentation and urgent help Post #345473
The things I mentioned aren't necessarily bad, but they do increase the risk of encountering problems like this, so personally I just don't use the carve tool, and I only rotate by 90 degrees. For slopes I mostly use the shearing tool and I stick to 'safe' slopes like 1:2, 1:3, 1:4, etc. For more complex shapes I use vertex manipulation, often giving brushes triangular faces, and I turn them into entities. For more intricate details it's better to use models.

Carving and rotating can produce tiny cracks between brushes, such as in the (exaggerated) picture below. With off-grid vertices, you might not even see a crack, but brushes can still be misaligned. The BSP process divides the inside of a level into convex areas (leaf nodes), using surfaces as dividing planes. Depending on how the process goes, that tiny crack could become a small convex area of its own, or it could produce a very thin but long area that extends towards the left, splitting other surfaces along the way. Maybe the cause of your problem is an almost infinitely thin crack like this:
User posted image
Posted 7 months ago2021-03-22 23:33:58 UTC
in Presentation and urgent help Post #345470
As far as I know, this problem has to do with numerical precision issues - I think it's caused by different planes that are so similar to each other that some part of the code incorrectly sees them as belonging to the same bsp leaf node. Or something like that. The VHLT tools apparently contain some improvements in that area, but you're already using those, so yeah.

Do you sometimes use the carve tool? Or do you rotate brushes freely? Does the map contain any off-grid vertices, or intersecting brushes whose intersection points are off the grid? Also, the log contains some coordinates (bounding boxes), are there sloped or slanted surfaces nearby?

If you still can't fix the problem, I could have a look if you're willing to send me the rmf/jmf.
Posted 7 months ago2021-03-19 11:57:51 UTC
in Post your screenshots! WIP thread Post #345456
I've been working on some wad and bsp tools recently. As a test, I extracted all textures from halflife.wad, ran a script to apply a black/white dithering effect, and then rebuilt the wad file. I also ran a script to make lightmaps grayscale, so if you always thought that Half-Life wasn't film-noir enough... then today's your day (just ignore the HUD sprites!):
User posted image
Adding small random offsets to vertices in a bsp file is also fun:
User posted image
Posted 7 months ago2021-03-12 22:49:51 UTC
in Help, can't replace textures in HL1 Post #345423
@23-down: maybe .tga was recommended because of things like gamma and color correction? I don't know whether Wally does anything with that, or how much those things really matter for an old game like Half-Life. Colors are surprisingly complicated... :|

@livewired: that's very interesting! Putting light_surface entities all over the place sounds like a lot of work though. Can't you get the effect you want with a proper lights.rad file or an info_texlights entity?
I'm not sure, but I think it only works if the grunt is already targeting that path_corner when it spawns. Monsters also seem to forget about the next path_corner after they've been interrupted, so if you want to force a monster to move to a certain location, it's better to use a scripted_sequence.
Posted 7 months ago2021-03-07 22:42:48 UTC
in Help, can't replace textures in HL1 Post #345404
@MenDax: the problem is that some HL singleplayer maps contain a reference to '\quiver\valve\sample.wad'. So when r_wadtextures is enabled, HL will crash because there is no sample.wad file. Fortunately that's easy to solve: just copy another wad file (or create an empty one, it doesn't matter) and rename it to 'sample.wad'.

A while ago I ran into the same issues as you did, but thanks to livewired's mention of r_wadtextures (thanks!) and an empty sample.wad file, I can finally finish that 'Half-Life: the Dithering' texture mod: :P
User posted image
@23-down: sorry for nitpicking, but... it's 256 colors, not 256-bit, and textures sizes must be multiples of 16 (due to mipmaps). .jpg is indeed a poor format for textures, but what's so special about .tga? And what does that have to do with map compile tools?
Posted 8 months ago2021-02-19 09:08:08 UTC
in Place osprey with command problem Post #345356
Apparently the monster_osprey's origin (position) has not been set, so it's placed at the default (0, 0, 0) position. I guess Xash3D's ent_create command will place entities at the point that you're looking at, but maybe that doesn't work correctly when you're looking at the sky, I don't know.

What happens when you use the ent_last_origin command after creating the path_corner? What happens when you manually specify the positions (ent_create path_corner targetname point origin "-200 -900 -1000", and ent_create monster_osprey target point origin "-200 -900 -1000")?

If that fixes the problem, but your game crashes, then that's because the path_corner doesn't have a target. There should be no 'dead ends' in the path that the monster_osprey is following. Maybe pointing the path_corner at itself will be sufficient, but if not, then you'll need at least 2 path_corners that target each other.
Posted 8 months ago2021-02-18 21:14:13 UTC
in TWHL Tower 2 Post #345354
That's a very ingenious solution indeed, Ogdred! Very nice.
Posted 9 months ago2021-01-24 23:24:00 UTC
in Lightmap resolution Post #345273
According to the descriptions of these settings, they affect how accurately light bouncing is calculated. They do not affect lightmap resolution. Only texture scale does.

From what I can find about the GoldSource bsp file format, it doesn't store separate texture coordinate information for lightmaps, so I think the 16:1 relationship is baked into the engine. There's nothing the compile tools can do to change that.
Posted 9 months ago2021-01-19 10:46:13 UTC
in Changelevel issus Post #345251
I don't have L4D(2), but comparing your screenshots against this guide doesn't show any obvious problems. Did you compile both maps before starting the game, and did they compile without errors? (otherwise one or both of the maps might be outdated) What actually happens when you enter the room?
I've taken a look at the 357 reloading code. Apart from a few events that can be specified in animations, much of the timing appears to be hard-coded. Ideally you'd want the code to react to the end of an animation, but I don't know enough about the HL engine to say whether that's possible.

CPython::Reload calls DefaultReload( 6, PYTHON_RELOAD, 2.0, bUseScope );, so the actual 'ammo transfer' happens after 2 seconds. Apparently that's when you can fire the weapon again, even if the reload animation hasn't finished yet.

DefaultReload also contains the line m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 3;, which causes CPython::WeaponIdle to pick a new idle animation after 3 seconds, regardless of whether the reload animation has finished. CPython::WeaponIdle also contains hard-coded durations for each of the idle/fidget animations.
Posted 9 months ago2021-01-14 23:13:26 UTC
in Ode to Lockdown [Map Jam] Post #345230
I don't know about padman, but the idea of a rats rats map sounds intriguing... Maybe I'll start working on something.
To make this work as intended, CBarney::BarneyFirePistol must be a virtual function. So in barney.cpp, change the following line:
void BarneyFirePistol( void );
virtual void BarneyFirePistol( void );
Without that, the code in CBarney will always call CBarney::BarneyFirePistol, instead of <type-of-current-object>::BarneyFirePistol.
Posted 9 months ago2021-01-13 08:40:08 UTC
in A custom animated Happy New Year from Black Mesa! Post #345213
Very nice! A happy new year to you, too!

I thought I heard a fireplace raging in the background, but you're telling me it was 8-bit noise? :walter:
Posted 9 months ago2021-01-11 17:06:51 UTC
in [HELP] Change level error/glitch Post #345203
Next time, please don't start multiple threads about the same problem (I'll remove the previous thread because this one contains more information).

Having said that, did you read my reply in your previous thread (see below)?
Do both maps contain an info_landmark with exactly the same name? And does each trigger_changelevel match an open, walkable space in the other level (relative to the landmarks)?

And just in case you haven't seen this yet: Tutorial: Changing Levels.
As that tutorial states, both maps must contain 1 info_landmark and 1 trigger_changelevel each, but it sounds like you've put both info_landmarks in the same level. Also, names are case-sensitive, so 'Ladm1' does not match 'ladm1'. Better stick to lowercase names everywhere, just to be safe. If you still can't get it to work after following that tutorial, consider uploading both maps to the vault so some of us can have a look at it.
Posted 9 months ago2021-01-10 22:21:27 UTC
in Help with tank prefab brushwork Post #345199
How could I forget... there's also shear mode. Create a brush for one side of the front of the turret, then use shearing to move one of the sides and the top backwards. Then use the clipping tool to cut off the back of the brush and to make the side of the turret slanted. Then copy this brush to the other side and flip it, and you should end up with a reasonable turret front.

And just as with vertex manipulation, it's better to stick to slope ratios like 1:2 and 1:4 and to use coarser grid sizes.
Posted 9 months ago2021-01-10 21:09:36 UTC
in Disable func_button Post #345198
One detail I forgot to mention: if you don't enable the 'Remove On fire' flag on a trigger_auto, then it will fire again when you reload a savegame that was made in that map. That will invert the button-multisource relationship again, which is not what you want. So be sure to enable that flag on each trigger_auto.
Posted 9 months ago2021-01-10 15:15:23 UTC
in train Post #345193
If you upload a test map to the vault then some of us could have a look. Without that it's difficult to see what's causing the problem.
Posted 9 months ago2021-01-09 17:19:13 UTC
in Buttons made using JACK not working! Post #345190
It's probably because the 'Health' attribute of your buttons is set to 1. That makes them only react to being shot.

I've got the same problem here. I normally press Ctrl+T to turn a brush into an entity, which turns it into the default brush entity (func_detail for me). I then start typing 'func_button' in the Class field, but by the time I type 'func_b' J.A.C.K. has selected 'func_breakable', and it'll add the attributes of that entity (including their default values). This sets 'Health' to 1. When I get to 'func_bu', J.A.C.K. knows it must be a func_button, but now it won't overwrite the existing 'Health' attribute anymore. Selecting 'func_button' from the Class dropdown list instead avoids the func_breakable detour.
Posted 9 months ago2021-01-09 15:00:58 UTC
in Help with tank prefab brushwork Post #345186
It looks like you've only been using the clipping tool so far? I don't think you can avoid vertex manipulation if you want to create a properly slanted M1 Abrams turret. The main rules for brushes are that they must be convex, and that all of their faces must be perfectly flat ('planar').

The M1 turret is a convex shape already, so that shouldn't be a problem, but it can still be useful to split it into multiple brushes (front/center/back), so each part can be manipulated separately.

Keeping faces flat is always tricky with slopes like this, but sticking to 'simple' slopes (1:2, 1:4, etc.) and coarser grid sizes can help reduce the chance that slope edges will meet at an off-the-grid point (this may cause non-planar faces). If that doesn't help, you can always use triangular faces. Either by starting with triangular brushes, or by splitting non-triangular faces by creating edges between vertices (this can be done by selecting them in vertex manipulation mode and pressing Ctrl+F).