pevhs.ch ~/tf2/nhcustom2/

Do not use the database shipped with the zip files! It is always outdated. Use the one stored here.
Dear anons of /tf2g/, prefer sending me an e-mail rather than talking about your issue in the thread.

Latest changes can be found in the website's feed (Atom/plain text).

Does a hat not behave according to your config file? Try using the path: header with its filename instead.


nhcustom2

This is a program whose purpose is to modify the Team Fortress 2 mod no-hats-bgum. If you plan to modify it to stop seeing specific hats or to handpick those you want to see, this tool should come in handy.

Note: a problem can arise when creating a custom version of no-hats-bgum, where cosmetics appear clipped inside default headgears. It isn't a problem with this program, but with how no-hats-bgum is made (and there is no fix). See this image for more information.

The program has been known to work on Windows 7, 10 and Fedora 36 (Linux). I don't offer any support with this program, but feel free to let me know if something doesn't work as expected or if the database contains errors.

The mod should work with other versions of "no-hats-mod" like Jarateking's CleanTF2plus, but this has not been thorougly tested.

Usage

In a nutshell: The program requires a configuration file, then based on the instructions (and on the database, which you must download here) copies from the input folder the hats specified over to the output folder. Here is an example of a basic configuration file:

#this is a comment
#the file must contain either "keep" or "remove"
keep

#everything will be removed, except the hats corresponding
#to the following parameters:
hat:Fancy Fedora
#quote names if they contain ! + or }
hat:"MONOCULUS!"
update:Mann-Conomy Update
#the "!" means that even though this hat is from the
#Mann-Conomy Update, it'll still be removed.
!hat:Bombing Run

Note: Windows users, don't forget to launch this program from the terminal. If the program were to encounter an error it will print the reason before quitting, but it can only be seen if the terminal stays open. Look at this to know how to do it.

Note: All patterns are regexes, so special regex characters must be escaped by a backslash, once if inside a quoted string, or twice if outside. Read more below.

Note: Most of the operations listed below are overkill if you just want to delete/make visible specific hats. Try not to get too lost into what is written here.

Arguments

The program accepts the following arguments:

The database

The database is a big CSV file containing all cosmetics with their filepaths, updates, etc. It should be encoded in UTF8 with no BOM and LF line endings.

The configuration file

The file must contain at least the words (called commands) remove or keep. These commands will make the program remove the specified hats or keep them with everything else removed, respectively.

The syntax is header:pattern, where header can be:

Those values, appart from "list", are taken from the first line of the database. You could add new entries, provided you do so in every line of the database. Note that headers cannot contain a colon. "list" is a reserved keyword.

All the headers apart from "date" can take any word or string as a pattern. the "date" header takes two dates separated by a forward slash in this format: YYYY-MM-DD/YYYY-MM-DD. (example: 2007-01-01/2009-12-31)

All the headers apart from "date" and "list" expect the given pattern to be a regular expression (regex). This means that if you wanted to search for all the hats that belong to the Scout, you wouldn't write class:Scout but class:^Scout$. The standard used for regexes is the Posix extended regular syntax.

Note: It is highly recommended to enclose regexes between two quotes, as the program treats backslashes as special characters that need to be doubled too. Doing so greatly simplifies things:

#Not ideal, the string is processed first
hat:The Voodoo Juju \\\(Slight Return\\\)
#More readable, the string is what the regex will be
hat:"The Voodoo Juju \(Slight Return\)"

If the quoted string must contain literal quotes, they must be written twice ("").

Flags

It's possible to "stack" multiple statements together by separating them with the flag +, ! or }. Doing so will modify the result that the previous statements found, on a per-line basis. If a flag were to be used at the start of a line, it will affect all the previous results. If you need to write those characters in a literal form, prepend them with a backslash (\!) or quote the text they're from.

If we imagine that the resuls from commands are A, B or C, here is a table showing the effects of the flags:

FlagEffect
+AB+C = ABC
!ABC!B = AC
}ABC}A = A

Note: one must pay attention when using the + flag. This flag, regardless if it's used in a line with multiple statements or not, will matches againts the entirety of the database. If you want to use it to make filters based on multiple statements, use parentheses, explained below.

See below for examples.

Parentheses

If one needs to filter results based on multiple criteria, it's possible to use parentheses between statements to bundle them together. The opening parenthesis must be placed after any flag. Examples:

#Select all pyro cosmetics that are head replacements OR that can also
#be worn by the medic.
class:Pyro}(equip:^Head Replacement$+class:Medic)

#Select the cosmetics between 2009 and 2012 IF they are either backpacks
#for the Pyro, or shoes for the Scout ONLY.
date:2009-01-01/2012-12-31}(class:^Pyro$}equip:^Back$+(class:^Scout$}equip:^Feet$))

#select all Smissmas 2022 hats for the Demoman, including the specific paths of
#all-class cosmetics.
update:smissmas 2022}(class:Demo+(class:All classes}path:demo))

Commands

When at the start of a line, some words have special meanings.

Lists

If you want to store the result of a search to use it later, you can use the "list" command. Results found while using this command will not affect the results found in previous lines. example:

list foo update:Smissmas 2022!list:bar

This will create a list named "foo" that contains the cosmetics released in the Smissmas 2022 update, apart from the ones that are in the already existing list "bar".

keep and remove

These commands specify wether the content of the configuration file must be kept in the game with everything removed, or removed from the game with everything else kept in. Only one of these commands must be used. If not specified, the program will assume the remove command.

erase

The erase command allows to render some hats that would have been replaced with the default hat invisible. For example, writing:

erase hat:"MONOCULUS!"

Will render the MONOCULUS! invisible, even though this hat is normally replaced with the default headgears.
Note: this command is only useful if you use nhcustom2 with the bgum version of no-hats-mod.

Other

Input and output folders

The input folder is where an uncompiled version of no-hats-bgum must be placed. The path should start with input/models/. The program will refuse to run if there isn't an input folder next to it and no other is specified with the "-i" argument. After the program is run, results will be placed in the output folder. Note that the output folder is not wiped between runs, so you must delete its content manually.

Compiling

On Linux, you can simply use the makefile in the repository, but you'll have to install MSYS2 if you're on Windows and use MinGW64 when executing the makefile.

This program has only been tested with glibc.

https://git.pevhs.ch/nhcustom2.git

More examples

#find hats that can be worn by mutiple classes but that are not all-class
#this is because the classes in the database are separated with a pipe.
class:"\|"

#deselect hats that came out between 2008 and march 1st, 2013, except
#if they can be worn by the soldier (alongside other classes)
!date:2008-01-01/2013-03-01!class:Soldier

#find all the hats containing the string "aaa"
hat:aaa

#find only the 1st style of the Millennial Mercenary
hat:millennial mercenary!path:style

#find every path with the word "scout" in them
path:scout

#find only the first style of the Foppish Physician
hat:foppish physician!path:necktie

#find only the third style of the medic cosmetics from Smissmas 2022
update:Smissmas 2022}class:^Medic$}path:style3

#create a list containing the Engineer's shirts and all VALVe-made hats for the spy
list mylist class:^Engineer$}equip:Shirt+(class:^Spy$}equip:Hat}path:models/player/items)

#find the Teufort Tooth Kicket only for the soldier and engineer
hat:Teufort Tooth Kicker}(path:soldier+path:engineer)

#find the first style of the All-Father for the heavy and soldier only
hat:All-Father}(path:heavy+path:soldier)!path:s2