This will delete the page "Dumping Particles"
. Please be certain.
Particles aren't exactly part of engine / game mod code, but there hasn't been a good way to dump it yet, so I wrote up a script to do just that.
Bash function to dump the particle files from the game package (output can be redirected):
dump_particle_systems() {
# dump particle system info
PACKAGE_FILE='/path/to/tf2_misc_dir.vpk'
script_dir='/path/to/pcfdump.py'
# extract to temporary directory
temp_dir=$(mktemp -d)
pushd "${temp_dir}" > /dev/null
mkdir particles
vpk x ${PACKAGE_FILE} `vpk l ${PACKAGE_FILE} | grep '\.pcf'` > /dev/null
python3 "${script_dir}"
popd > /dev/null
if [[ -d ${temp_dir} ]]; then
rm -r "${temp_dir}"
fi
}
Python script to parse all the unique PCF files and output sorted particle system names:
#!/usr/bin/python3
import struct
import pathlib
ignored_suffixes = [ '_high', '_dx80', '_dx90_slow' ]
def unpack(fmt, stream):
'''
unpacks values from a stream
source: https://stackoverflow.com/a/17537253
'''
size = struct.calcsize(fmt)
buf = stream.read(size)
return struct.unpack(fmt, buf)
def unpack_string(stream, offset = None, encoding = 'utf-8'):
''' unpacks a variable-length, zero-terminated string from a stream '''
if offset is not None:
stream.seek(offset)
return bytes(iter(lambda: ord(stream.read(1)), 0)).decode(encoding)
particle_map = {}
# dumps particle names from particles/*.pcf
for filepath in pathlib.Path('particles').glob('*.pcf'):
string_dict = []
particle_list = []
if any(filepath.stem.endswith(suffix) for suffix in ignored_suffixes):
continue
with open(str(filepath), 'rb') as particle_file:
header = unpack_string(particle_file)
# string table
num_strings, *_ = unpack('<H', particle_file)
for _ in range(0, num_strings):
string_entry = unpack_string(particle_file)
string_dict.append(string_entry)
num_elements, *_ = unpack('<I', particle_file)
for _ in range(0, num_elements):
# CDmxElement
index, *_ = unpack('<H', particle_file)
element_name = unpack_string(particle_file)
sig = unpack('<16c', particle_file)
if string_dict[index] == 'DmeParticleSystemDefinition':
particle_list.append(element_name)
particle_map[filepath.stem] = particle_list
# dump the stuff
for filename, particle_list in sorted(particle_map.items()):
print(filename)
print(*('\t' + p for p in sorted(particle_list)), sep = '\n')
This will delete the page "Dumping Particles"
. Please be certain.